rx-internal-use-static-inline-macro-20090407
[openafs.git] / src / rx / rx_internal.h
1 /*
2  * Copyright (c) 2008, Your File System, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without 
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, 
9  *    this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright 
11  *    notice, this list of conditions and the following disclaimer in the 
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the company nor the names of its contributors may 
14  *    be used to endorse or promote products derived from this software 
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #ifndef _RX_INTERNAL_H_
31 #define _RX_INTERNAL_H_
32
33 #ifdef AFS_DARWIN80_ENV
34 #include <libkern/OSAtomic.h>
35 #endif
36 #ifdef AFS_SUN58_ENV
37 #include <sys/atomic.h>
38 #endif
39
40 #ifdef AFS_NT40_ENV
41 #ifndef _WIN64
42 #ifndef __cplusplus
43 #include <intrin.h>
44 #pragma intrinsic(_InterlockedOr)
45 #pragma intrinsic(_InterlockedAnd)
46 #define rx_AtomicOr(object, operand, mutex) _InterlockedOr(&object, operand)
47 #define rx_AtomicAnd(object, operand, mutex) _InterlockedAnd(&object, operand)
48 #endif /* __cplusplus */
49 #else /* !WIN64 */
50 #define rx_AtomicOr(object, operand, mutex) InterlockedOr(&object, operand)
51 #define rx_AtomicAnd(object, operand, mutex) InterlockedAnd(&object, operand)
52 #endif /* WIN64 */
53 #define rx_AtomicIncrement_NL(object) InterlockedIncrement(&object)
54 #define rx_AtomicIncrement(object, mutex) InterlockedIncrement(&object)
55 #define rx_AtomicXor(object, operand, mutex) InterlockedXor(&object, operand)
56 #define rx_AtomicAdd_NL(object, addend) InterlockedExchangeAdd(&object, addend)
57 #define rx_AtomicAdd(object, addend, mutex) InterlockedExchangeAdd(&object, addend)
58 #define rx_AtomicDecrement_NL(object) InterlockedDecrement(&object)
59 #define rx_AtomicDecrement(object, mutex) InterlockedDecrement(&object)
60 #define rx_AtomicSwap_NL(object1, object2) InterlockedExchange ((volatile LONG *) object1, object2);
61 #define rx_AtomicSwap(object1, object2, mutex) InterlockedExchange ((volatile LONG *) object1, object2);
62 #elif defined(AFS_DARWIN80_ENV)
63 #define rx_AtomicIncrement_NL(object) OSAtomicIncrement32(&object)
64 #define rx_AtomicIncrement(object, mutex) OSAtomicIncrement32(&object)
65 #define rx_AtomicOr(object, operand, mutex) OSAtomicOr32(operand, &object)
66 #define rx_AtomicAnd(object, operand, mutex) OSAtomicAnd32(operand, &object)
67 #define rx_AtomicXor(object, operand, mutex) OSAtomicXor32(operand, &object)
68 #define rx_AtomicAdd_NL(object, addend) OSAtomicAdd32(addend, &object)
69 #define rx_AtomicAdd(object, addend, mutex) OSAtomicAdd32(addend, &object)
70 #define rx_AtomicDecrement_NL(object) OSAtomicDecrement32(&object)
71 #define rx_AtomicDecrement(object, mutex) OSAtomicDecrement32(&object)
72 #define rx_AtomicSwap_NL(oldval, newval) rx_AtomicSwap_int(oldval, newval)
73 #define rx_AtomicSwap(oldval, newval, mutex) rx_AtomicSwap_int(oldval, newval)
74 static inline afs_int32 rx_AtomicSwap_int(afs_int32 *oldval, afs_int32 newval) {
75     afs_int32 ret = *oldval;
76     OSAtomicCompareAndSwap32 ((afs_int32) *oldval,(afs_int32) newval,
77                               (afs_int32*) oldval);
78     return ret;
79 }
80 #elif defined(AFS_SUN58_ENV)
81 #define rx_AtomicIncrement_NL(object) atomic_inc_32(&object)
82 #define rx_AtomicIncrement(object, mutex) atomic_inc_32(&object)
83 #define rx_AtomicOr(object, operand, mutex) atomic_or_32(&object, operand)
84 #define rx_AtomicAnd(object, operand, mutex) atomic_and_32(&object, operand)
85 #define rx_AtomicAdd_NL(object, addend) atomic_add_32(&object, addend)
86 #define rx_AtomicAdd(object, addend, mutex) atomic_add_32(&object, addend)
87 #define rx_AtomicDecrement_NL(object) atomic_dec_32(&object)
88 #define rx_AtomicDecrement(object, mutex) atomic_dec_32(&object)
89 #define rx_AtomicSwap_NL(oldval, newval) rx_AtomicSwap_int(oldval, newval)
90 #define rx_AtomicSwap(oldval, newval, mutex) rx_AtomicSwap_int(oldval, newval)
91 static inline afs_int32 rx_AtomicSwap_int(afs_int32 *oldval, afs_int32 newval) {
92     afs_int32 ret = *oldval;
93     atomic_cas_32((afs_int32) *oldval,(afs_int32) newval,
94                   (afs_int32*) oldval);
95     return ret;
96 }
97 #else
98 #define rx_AtomicIncrement_NL(object) (object)++
99 #define rx_AtomicIncrement(object, mutex) rx_MutexIncrement(object, mutex)
100 #define rx_AtomicOr(object, operand, mutex) rx_MutexOr(object, operand, mutex)
101 #define rx_AtomicAnd(object, operand, mutex) rx_MutexAnd(object, operand, mutex)
102 #define rx_AtomicAdd_NL(object, addend) (object += addend)
103 #define rx_AtomicAdd(object, addend, mutex) rx_MutexAdd(object, addand, mutex)
104 #define rx_AtomicDecrement_NL(object) (object)--
105 #define rx_AtomicDecrement(object, mutex) rx_MutexDecrement(object, mutex)
106 #define rx_AtomicSwap_NL(oldval, newval) rx_AtomicSwap_int(oldval, newval)
107 #define rx_AtomicSwap(oldval, newval, mutex) rx_AtomicSwap_int(oldval, newval)
108 static_inline afs_int32 rx_AtomicSwap_int(afs_int32 *oldval, afs_int32 newval) {
109     afs_int32 ret = *oldval;
110     *oldval = newval;
111     return ret;
112 }
113 #endif
114 #define rx_AtomicPeek_NL(object) rx_AtomicAdd_NL(object, 0)
115 #define rx_AtomicPeek(object, mutex) rx_AtomicAdd(object, 0, mutex)
116 #define rx_MutexIncrement(object, mutex) \
117     do { \
118         MUTEX_ENTER(&mutex); \
119         object++; \
120         MUTEX_EXIT(&mutex); \
121     } while(0)
122 #define rx_MutexOr(object, operand, mutex) \
123     do { \
124         MUTEX_ENTER(&mutex); \
125         object |= operand; \
126         MUTEX_EXIT(&mutex); \
127     } while(0)
128 #define rx_MutexAnd(object, operand, mutex) \
129     do { \
130         MUTEX_ENTER(&mutex); \
131         object &= operand; \
132         MUTEX_EXIT(&mutex); \
133     } while(0)
134 #define rx_MutexXor(object, operand, mutex) \
135     do { \
136         MUTEX_ENTER(&mutex); \
137         object ^= operand; \
138         MUTEX_EXIT(&mutex); \
139     } while(0)
140 #define rx_MutexAdd(object, addend, mutex) \
141     do { \
142         MUTEX_ENTER(&mutex); \
143         object += addend; \
144         MUTEX_EXIT(&mutex); \
145     } while(0)
146 #define rx_MutexDecrement(object, mutex) \
147     do { \
148         MUTEX_ENTER(&mutex); \
149         object--; \
150         MUTEX_EXIT(&mutex); \
151     } while(0)
152 #define rx_MutexAdd1Increment2(object1, addend, object2, mutex) \
153     do { \
154         MUTEX_ENTER(&mutex); \
155         object1 += addend; \
156         object2++; \
157         MUTEX_EXIT(&mutex); \
158     } while(0)
159 #define rx_MutexAdd1Decrement2(object1, addend, object2, mutex) \
160     do { \
161         MUTEX_ENTER(&mutex); \
162         object1 += addend; \
163         object2--; \
164         MUTEX_EXIT(&mutex); \
165     } while(0)
166
167 #define rx_MutexAdd1AtomicIncrement2(object1, addend, object2, mutex) \
168     do { \
169         MUTEX_ENTER(&mutex); \
170         object1 += addend; \
171         rx_AtomicIncrement(&object2); \
172         MUTEX_EXIT(&mutex); \
173     } while (0)
174 #define rx_MutexAdd1AtomicDecrement2(object1, addend, object2, mutex) \
175     do { \
176         MUTEX_ENTER(&mutex); \
177         object1 += addend; \
178         rx_AtomicDecrement(&object2); \
179         MUTEX_EXIT(&mutex); \
180     } while (0)
181 #endif /* _RX_INTERNAL_H */