This is Unofficial EPICS BASE Doxygen Site
epicsAtomicMS.h
Go to the documentation of this file.
1 
2 /*************************************************************************\
3 * Copyright (c) 2011 LANS LLC, as Operator of
4 * Los Alamos National Laboratory.
5 * Copyright (c) 2011 UChicago Argonne LLC, as Operator of Argonne
6 * National Laboratory.
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
13  * johill@lanl.gov
14  */
15 
16 #ifndef epicsAtomicMS_h
17 #define epicsAtomicMS_h
18 
19 #include "epicsAssert.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif /* __cplusplus */
24 
25 #ifndef EPICS_ATOMIC_INCR_INTT
26 #define EPICS_ATOMIC_INCR_INTT
28 {
29  STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) );
30  MS_LONG * const pTarg = ( MS_LONG * ) pTarget;
31  return MS_InterlockedIncrement ( pTarg );
32 }
33 #endif
34 
35 #ifndef EPICS_ATOMIC_DECR_INTT
36 #define EPICS_ATOMIC_DECR_INTT
38 {
39  STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) );
40  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
41  return MS_InterlockedDecrement ( pTarg );
42 }
43 #endif
44 
45 #ifndef EPICS_ATOMIC_ADD_INTT
46 #define EPICS_ATOMIC_ADD_INTT
47 EPICS_ATOMIC_INLINE int epicsAtomicAddIntT ( int * pTarget, int delta )
48 {
49  STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) );
50  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
51  /* we dont use InterlockedAdd because only latest windows is supported */
52  return delta + ( int ) MS_InterlockedExchangeAdd ( pTarg,
53  ( MS_LONG ) delta );
54 }
55 #endif
56 
57 #ifndef EPICS_ATOMIC_CAS_INTT
58 #define EPICS_ATOMIC_CAS_INTT
60  int oldVal, int newVal )
61 {
62  STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( int ) );
63  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
64  return (int) MS_InterlockedCompareExchange ( pTarg,
65  (MS_LONG) newVal, (MS_LONG) oldVal );
66 }
67 #endif
68 
69 #if ! defined ( MS_ATOMIC_64 )
70 
71 /*
72  * necessary for next three functions
73  *
74  * looking at the MS documentation it appears that they will
75  * keep type long the same size as an int on 64 bit builds
76  */
77 STATIC_ASSERT ( sizeof ( MS_LONG ) == sizeof ( size_t ) );
78 
79 #ifndef EPICS_ATOMIC_INCR_SIZET
80 #define EPICS_ATOMIC_INCR_SIZET
81 EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget )
82 {
83  MS_LONG * const pTarg = ( MS_LONG * ) pTarget;
84  return MS_InterlockedIncrement ( pTarg );
85 }
86 #endif
87 
88 #ifndef EPICS_ATOMIC_DECR_SIZET
89 #define EPICS_ATOMIC_DECR_SIZET
90 EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget )
91 {
92  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
93  return MS_InterlockedDecrement ( pTarg );
94 }
95 #endif
96 
97 #ifndef EPICS_ATOMIC_ADD_SIZET
98 #define EPICS_ATOMIC_ADD_SIZET
99 EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget,
100  size_t delta )
101 {
102  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
103  /* we dont use InterlockedAdd because only latest windows is supported */
104  return delta + ( size_t ) MS_InterlockedExchangeAdd ( pTarg,
105  ( MS_LONG ) delta );
106 }
107 #endif
108 
109 #ifndef EPICS_ATOMIC_SUB_SIZET
110 #define EPICS_ATOMIC_SUB_SIZET
111 EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta )
112 {
113  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
114  MS_LONG ldelta = (MS_LONG) delta;
115  /* we dont use InterlockedAdd because only latest windows is supported */
116  return ( ( size_t ) MS_InterlockedExchangeAdd ( pTarg, -ldelta ) ) - delta;
117 }
118 #endif
119 
120 #ifndef EPICS_ATOMIC_CAS_SIZET
121 #define EPICS_ATOMIC_CAS_SIZET
123  size_t * pTarget,
124  size_t oldVal, size_t newVal )
125 {
126  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
127  return (size_t) MS_InterlockedCompareExchange ( pTarg,
128  (MS_LONG) newVal, (MS_LONG) oldVal );
129 }
130 #endif
131 
132 #ifndef EPICS_ATOMIC_CAS_PTRT
133 #define EPICS_ATOMIC_CAS_PTRT
135  EpicsAtomicPtrT * pTarget,
136  EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal )
137 {
138  MS_LONG * const pTarg = ( MS_LONG * ) ( pTarget );
140  (MS_LONG) newVal, (MS_LONG) oldVal );
141 }
142 #endif
143 
144 #else /* ! MS_ATOMIC_64 */
145 
146 /*
147  * necessary for next three functions
148  */
149 STATIC_ASSERT ( sizeof ( MS_LONGLONG ) == sizeof ( size_t ) );
150 
151 #ifndef EPICS_ATOMIC_INCR_SIZET
152 #define EPICS_ATOMIC_INCR_SIZET
153 EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT ( size_t * pTarget )
154 {
155  MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) pTarget;
156  return ( size_t ) MS_InterlockedIncrement64 ( pTarg );
157 }
158 #endif
159 
160 #ifndef EPICS_ATOMIC_DECR_SIZET
161 #define EPICS_ATOMIC_DECR_SIZET
162 EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT ( size_t * pTarget )
163 {
164  MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget );
165  return ( size_t ) MS_InterlockedDecrement64 ( pTarg );
166 }
167 #endif
168 
169 #ifndef EPICS_ATOMIC_ADD_SIZET
170 #define EPICS_ATOMIC_ADD_SIZET
171 EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT ( size_t * pTarget, size_t delta )
172 {
173  MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget );
174  /* we dont use InterlockedAdd64 because only latest windows is supported */
175  return delta + ( size_t ) MS_InterlockedExchangeAdd64 ( pTarg,
176  ( MS_LONGLONG ) delta );
177 }
178 #endif
179 
180 #ifndef EPICS_ATOMIC_SUB_SIZET
181 #define EPICS_ATOMIC_SUB_SIZET
182 EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT ( size_t * pTarget, size_t delta )
183 {
184  MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget );
185  MS_LONGLONG ldelta = (MS_LONGLONG) delta;
186  /* we dont use InterlockedAdd64 because only latest windows is supported */
187  return (( size_t ) MS_InterlockedExchangeAdd64 ( pTarg, -ldelta )) - delta;
188 }
189 #endif
190 
191 #ifndef EPICS_ATOMIC_CAS_SIZET
192 #define EPICS_ATOMIC_CAS_SIZET
193 EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT ( size_t * pTarget,
194  size_t oldVal, size_t newVal )
195 {
196  MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget );
197  return (size_t) MS_InterlockedCompareExchange64 ( pTarg,
198  (MS_LONGLONG) newVal,
199  (MS_LONGLONG) oldVal );
200 }
201 #endif
202 
203 #ifndef EPICS_ATOMIC_CAS_PTRT
204 #define EPICS_ATOMIC_CAS_PTRT
206  EpicsAtomicPtrT * pTarget,
207  EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal )
208 {
209  MS_LONGLONG * const pTarg = ( MS_LONGLONG * ) ( pTarget );
210  return (EpicsAtomicPtrT) MS_InterlockedCompareExchange64 ( pTarg,
211  (MS_LONGLONG) newVal, (MS_LONGLONG) oldVal );
212 }
213 #endif
214 
215 #endif /* ! MS_ATOMIC_64 */
216 
217 #ifdef __cplusplus
218 } /* end of extern "C" */
219 #endif /* __cplusplus */
220 
221 #endif /* ifdef epicsAtomicMS_h */
222 
EPICS_ATOMIC_INLINE size_t epicsAtomicAddSizeT(size_t *pTarget, size_t delta)
Definition: epicsAtomicMS.h:99
#define MS_InterlockedIncrement
EPICS_ATOMIC_INLINE int epicsAtomicDecrIntT(int *pTarget)
Definition: epicsAtomicMS.h:37
An EPICS-specific replacement for ANSI C's assert.
EPICS_ATOMIC_INLINE size_t epicsAtomicSubSizeT(size_t *pTarget, size_t delta)
EPICS_ATOMIC_INLINE EpicsAtomicPtrT epicsAtomicCmpAndSwapPtrT(EpicsAtomicPtrT *pTarget, EpicsAtomicPtrT oldVal, EpicsAtomicPtrT newVal)
STATIC_ASSERT(sizeof(MS_LONG)==sizeof(size_t))
void * EpicsAtomicPtrT
Definition: epicsAtomic.h:28
#define MS_LONG
#define MS_InterlockedCompareExchange
#define EPICS_ATOMIC_INLINE
Definition: epicsAtomic.h:22
EPICS_ATOMIC_INLINE size_t epicsAtomicDecrSizeT(size_t *pTarget)
Definition: epicsAtomicMS.h:90
#define MS_InterlockedDecrement
EPICS_ATOMIC_INLINE int epicsAtomicIncrIntT(int *pTarget)
Definition: epicsAtomicMS.h:27
#define MS_InterlockedExchangeAdd
EPICS_ATOMIC_INLINE size_t epicsAtomicCmpAndSwapSizeT(size_t *pTarget, size_t oldVal, size_t newVal)
EPICS_ATOMIC_INLINE int epicsAtomicCmpAndSwapIntT(int *pTarget, int oldVal, int newVal)
Definition: epicsAtomicMS.h:59
EPICS_ATOMIC_INLINE size_t epicsAtomicIncrSizeT(size_t *pTarget)
Definition: epicsAtomicMS.h:81
EPICS_ATOMIC_INLINE int epicsAtomicAddIntT(int *pTarget, int delta)
Definition: epicsAtomicMS.h:47