EPICS Base  7.0.6.1
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
epicsAtomic.h
1 /*************************************************************************\
2 * Copyright (c) 2011 LANS LLC, as Operator of
3 * Los Alamos National Laboratory.
4 * Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
5 * National Laboratory.
6 * SPDX-License-Identifier: EPICS
7 * EPICS BASE is distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 
11 /*
12  * Author Jeffrey O. Hill
14  */
15 
16 #ifndef epicsAtomic_h
17 #define epicsAtomic_h
18 
19 #include <stdlib.h> /* define size_t */
20 
21 #include "compilerSpecific.h"
22 
23 #define EPICS_ATOMIC_INLINE static EPICS_ALWAYS_INLINE
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 typedef void * EpicsAtomicPtrT;
30 
31 /* load target into cache */
32 EPICS_ATOMIC_INLINE void epicsAtomicReadMemoryBarrier (void);
33 
34 /* push cache version of target into target */
35 EPICS_ATOMIC_INLINE void epicsAtomicWriteMemoryBarrier (void);
36 
37 /*
38  * lock out other smp processors from accessing the target,
39  * load target into cache, add one to target, flush cache
40  * to target, allow other smp processors to access the target,
41  * return new value of target as modified by this operation
42  */
43 EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget );
44 EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT ( int * pTarget );
45 
46 /*
47  * lock out other smp processors from accessing the target,
48  * load target into cache, subtract one from target, flush cache
49  * to target, allow out other smp processors to access the target,
50  * return new value of target as modified by this operation
51  */
52 EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget );
53 EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT ( int * pTarget );
54 
55 /*
56  * lock out other smp processors from accessing the target,
57  * load target into cache, add/sub delta to/from target, flush cache
58  * to target, allow other smp processors to access the target,
59  * return new value of target as modified by this operation
60  */
61 EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta );
62 EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta );
63 EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta );
64 
65 /*
66  * set cache version of target, flush cache to target
67  */
68 EPICS_ATOMIC_INLINE void epicsAtomicSetSizeT ( size_t * pTarget, size_t newValue );
69 EPICS_ATOMIC_INLINE void epicsAtomicSetIntT ( int * pTarget, int newValue );
70 EPICS_ATOMIC_INLINE void epicsAtomicSetPtrT ( EpicsAtomicPtrT * pTarget, EpicsAtomicPtrT newValue );
71 
72 /*
73  * fetch target into cache, return new value of target
74  */
75 EPICS_ATOMIC_INLINE size_t epicsAtomicGetSizeT ( const size_t * pTarget );
76 EPICS_ATOMIC_INLINE int epicsAtomicGetIntT ( const int * pTarget );
77 EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicGetPtrT ( const EpicsAtomicPtrT * pTarget );
78 
79 /*
80  * lock out other smp processors from accessing the target,
81  * load target into cache, if target is equal to oldVal set target
82  * to newVal, flush cache to target, allow other smp processors
83  * to access the target, return the original value stored in the
84  * target
85  */
86 EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget,
87  size_t oldVal, size_t newVal );
88 EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT ( int * pTarget,
89  int oldVal, int newVal );
90 EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT (
91  EpicsAtomicPtrT * pTarget,
92  EpicsAtomicPtrT oldVal,
93  EpicsAtomicPtrT newVal );
94 
95 #ifdef __cplusplus
96 } /* end of extern "C" */
97 #endif
98 
99 /*
100  * options for in-line compiler intrinsic or OS specific
101  * implementations of the above function prototypes
102  *
103  * for some of the compilers we must define the
104  * in-line functions before they get used in the c++
105  * in-line functions below
106  */
107 #include "epicsAtomicCD.h"
108 
109 #ifdef __cplusplus
110 
111 namespace epics {
112 namespace atomic {
113 
114 /*
115  * overloaded c++ interface
116  */
117 
118 /************* incr ***************/
119 EPICS_ATOMIC_INLINE size_t increment ( size_t & v )
120 {
121  return epicsAtomicIncrSizeT ( & v );
122 }
123 
124 EPICS_ATOMIC_INLINE int increment ( int & v )
125 {
126  return epicsAtomicIncrIntT ( & v );
127 }
128 
129 /************* decr ***************/
130 EPICS_ATOMIC_INLINE size_t decrement ( size_t & v )
131 {
132  return epicsAtomicDecrSizeT ( & v );
133 }
134 
135 EPICS_ATOMIC_INLINE int decrement ( int & v )
136 {
137  return epicsAtomicDecrIntT ( & v );
138 }
139 
140 /************* add ***************/
141 EPICS_ATOMIC_INLINE size_t add ( size_t & v, size_t delta )
142 {
143  return epicsAtomicAddSizeT ( & v, delta );
144 }
145 
146 EPICS_ATOMIC_INLINE int add ( int & v, int delta )
147 {
148  return epicsAtomicAddIntT ( & v, delta );
149 }
150 
151 /************* sub ***************/
152 EPICS_ATOMIC_INLINE size_t subtract ( size_t & v, size_t delta )
153 {
154  return epicsAtomicSubSizeT ( & v, delta );
155 }
156 
157 EPICS_ATOMIC_INLINE int subtract ( int & v, int delta )
158 {
159  return epicsAtomicAddIntT ( & v, -delta );
160 }
161 
162 /************* set ***************/
163 EPICS_ATOMIC_INLINE void set ( size_t & v , size_t newValue )
164 {
165  epicsAtomicSetSizeT ( & v, newValue );
166 }
167 
168 EPICS_ATOMIC_INLINE void set ( int & v, int newValue )
169 {
170  epicsAtomicSetIntT ( & v, newValue );
171 }
172 
173 EPICS_ATOMIC_INLINE void set ( EpicsAtomicPtrT & v, EpicsAtomicPtrT newValue )
174 {
175  epicsAtomicSetPtrT ( & v, newValue );
176 }
177 
178 /************* get ***************/
179 EPICS_ATOMIC_INLINE size_t get ( const size_t & v )
180 {
181  return epicsAtomicGetSizeT ( & v );
182 }
183 
184 EPICS_ATOMIC_INLINE int get ( const int & v )
185 {
186  return epicsAtomicGetIntT ( & v );
187 }
188 
189 EPICS_ATOMIC_INLINE EpicsAtomicPtrT get ( const EpicsAtomicPtrT & v )
190 {
191  return epicsAtomicGetPtrT ( & v );
192 }
193 
194 /************* cas ***************/
195 EPICS_ATOMIC_INLINE size_t compareAndSwap ( size_t & v,
196  size_t oldVal, size_t newVal )
197 {
198  return epicsAtomicCmpAndSwapSizeT ( & v, oldVal, newVal );
199 }
200 
201 EPICS_ATOMIC_INLINE int compareAndSwap ( int & v, int oldVal, int newVal )
202 {
203  return epicsAtomicCmpAndSwapIntT ( & v, oldVal, newVal );
204 }
205 
206 EPICS_ATOMIC_INLINE EpicsAtomicPtrT compareAndSwap ( EpicsAtomicPtrT & v,
207  EpicsAtomicPtrT oldVal,
208  EpicsAtomicPtrT newVal )
209 {
210  return epicsAtomicCmpAndSwapPtrT ( & v, oldVal, newVal );
211 }
212 
213 } /* end of name space atomic */
214 } /* end of name space epics */
215 
216 #endif /* ifdef __cplusplus */
217 
218 #endif /* epicsAtomic_h */