1 mike 1.1 /*
2 **==============================================================================
3 **
4 ** Open Management Infrastructure (OMI)
5 **
6 ** Copyright (c) Microsoft Corporation
7 **
8 ** Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 ** use this file except in compliance with the License. You may obtain a copy
10 ** of the License at
11 **
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 **
14 ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
16 ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
17 ** MERCHANTABLITY OR NON-INFRINGEMENT.
18 **
19 ** See the Apache 2 License for the specific language governing permissions
20 ** and limitations under the License.
21 **
22 mike 1.1 **==============================================================================
23 */
24
25 #ifndef _base_atomic_h
26 #define _base_atomic_h
27
28 #include <common.h>
29
30 BEGIN_EXTERNC
31
32 /*
33 **==============================================================================
34 **
35 ** Windows Atomic Type
36 **
37 **==============================================================================
38 */
39
40 #if !defined(HAVE_ATOMIC) && defined(_WIN32)
41 # define HAVE_ATOMIC
42 END_EXTERNC
43 mike 1.1 # include <winbase.h>
44 BEGIN_EXTERNC
45
46 typedef long AtomicInt;
47
48 MI_INLINE void AtomicInc(AtomicInt* x)
49 {
50 InterlockedIncrement(x);
51 }
52
53 MI_INLINE unsigned char AtomicDec(AtomicInt* x)
54 {
55 return InterlockedDecrement(x) == 0;
56 }
57
58 #endif
59
60 /*
61 **==============================================================================
62 **
63 ** Linux Atomic Type
64 mike 1.1 **
65 **==============================================================================
66 */
67
68 #if !defined(HAVE_ATOMIC) && defined(linux)
69 # define HAVE_ATOMIC
70
71 typedef volatile long AtomicInt;
72
73 MI_INLINE void AtomicInc(AtomicInt* v)
74 {
75 __asm__ __volatile__(
76 "lock ; " "incl %0"
77 :"=m" (*v)
78 :"m" (*v));
79 }
80
81 MI_INLINE unsigned char AtomicDec(AtomicInt* v)
82 {
83 unsigned char c;
84
85 mike 1.1 __asm__ __volatile__(
86 "lock ; " "decl %0; sete %1"
87 :"=m" (*v), "=qm" (c)
88 :"m" (*v) : "memory");
89 return c != 0;
90 }
91
92 #endif
93
94 /*
95 **==============================================================================
96 **
97 ** SunOs
98 **
99 **==============================================================================
100 */
101
102 #if !defined(HAVE_ATOMIC) && defined(sun) && defined(__SunOS_5_10)
103 # define HAVE_ATOMIC
104 END_EXTERNC
105 # include <inttypes.h>
106 mike 1.1 # include <atomic.h>
107 BEGIN_EXTERNC
108
109 typedef volatile unsigned long long AtomicInt;
110
111 MI_INLINE void AtomicInc(AtomicInt* x)
112 {
113 atomic_inc_64(x);
114 }
115
116 MI_INLINE unsigned char AtomicDec(AtomicInt* x)
117 {
118 return atomic_dec_64_nv(x) == 0;
119 }
120
121 #endif
122
123 /*
124 **==============================================================================
125 **
126 ** Sun Sparc
127 mike 1.1 **
128 **==============================================================================
129 */
130
131 #if !defined(HAVE_ATOMIC) && defined(sun)
132 # define HAVE_ATOMIC
133
134 typedef long AtomicInt;
135
136 EXTERNC AtomicInt AtomicDecrement(AtomicInt* pValue);
137
138 EXTERNC AtomicInt AtomicIncrement(AtomicInt* pValue);
139
140
141 MI_INLINE void AtomicInc(AtomicInt* x)
142 {
143 AtomicIncrement(x);
144 }
145
146 MI_INLINE unsigned char AtomicDec(AtomicInt* x)
147 {
148 mike 1.1 return AtomicDecrement(x) == 0;
149 }
150
151 #endif
152
153 /*
154 **==============================================================================
155 **
156 ** AIX
157 **
158 **==============================================================================
159 */
160
161 #if defined(aix) && !defined(HAVE_ATOMIC)
162 # define HAVE_ATOMIC
163 END_EXTERNC
164 # include <sys/atomic_op.h>
165 BEGIN_EXTERNC
166
167 typedef int AtomicInt;
168
169 mike 1.1 MI_INLINE void AtomicInc(AtomicInt* x)
170 {
171 fetch_and_add(x, 1);
172 }
173
174 MI_INLINE unsigned char AtomicDec(AtomicInt* x)
175 {
176 return fetch_and_add(x, -1) - 1 == 0;
177 }
178
179 #endif
180
181 /*
182 **==============================================================================
183 **
184 ** Generic
185 **
186 **==============================================================================
187 */
188
189 #if !defined(HAVE_ATOMIC)
190 mike 1.1
191 typedef int AtomicInt;
192
193 void AtomicInc(AtomicInt* x);
194
195 unsigned char AtomicDec(AtomicInt* x);
196
197 #define MI_DEFAULT_ATOMIC_REQUIRED
198
199 #endif
200
201 END_EXTERNC
202
203 #endif /* _base_atomic_h */
|