Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cInterlockedVal.h
Go to the documentation of this file.
1 //
5 //
7 
8 #ifndef _INC_cInterlockedVal_H
9 #define _INC_cInterlockedVal_H
10 #ifndef NO_PRAGMA_ONCE
11 #pragma once
12 #endif
13 
14 #include "Index.h"
15 #include "cUnitTestDecl.h"
16 
17 namespace Gray
18 {
19 
20 #define _SIZEOF_INT 4
21 #if defined(USE_64BIT) && defined(__GNUC__)
22 #define _SIZEOF_LONG 8
23 #else
24 #define _SIZEOF_LONG 4
25 #endif
26 
27 #if defined(_M_IX86) && (_MSC_VER >= 1000)
28 #pragma warning(disable:4035) // disable the no return value warning, because of assembly language
29 #endif
30 
31  //*************************************************************
32  // 32 bit values. INT32
33 
34 #if defined(_WIN32)
36  typedef LONG INTER32_t;
37 
38  // Use intrinsic interlock if possible. _MSC_VER
39  // #pragma intrinsic( _InterlockedIncrement, _InterlockedDecrement, _InterlockedExchange, _InterlockedExchangeAdd, _InterlockedCompareExchange )
40 
41 #else
42  // __linux__ using __GNUC__
43 
44  typedef INT32 INTER32_t;
45 
46  struct __synch_xchg_INT32 { INT32 a[4]; }; // was a[100]
47 #define __synch_xg(x) ((struct __synch_xchg_INT32 *)(x))
48 
49  inline INT32 __cdecl InterlockedCompareExchange(INT32 VOLATILE* pDest, INT32 nValNew, INT32 nValComp) noexcept
50  {
56 
57 #if defined(__GNUC__)
58  INT32 nValPrev;
59 
60 #if 0
61  // from "jslock.c"
62  __asm__ __volatile__
63  (
64  "lock\n"
65  "cmpxchgl %2, (%1)\n"
66  "sete %%al\n"
67  "andl $1, %%eax\n"
68  : "=a" (nValPrev)
69  : "r" (pDest), "r" (nValNew), "a" (nValComp)
70  : "cc", "memory"
71  );
72 #endif
73 
74  __asm__ __volatile__
75  (
76  "lock\n"
77 #ifdef USE_64BIT
78  "cmpxchgl %k1,%2"
79 #else
80  "cmpxchgl %1,%2"
81 #endif
82  : "=a"(nValPrev)
83  : "q"(nValNew), "m"(*__synch_xg(pDest)), "0"(nValComp)
84  : "memory"
85  );
86  return nValPrev;
87 #elif defined(_M_IX86) // _MSC_VER 32 bit
88  __asm
89  {
90  MOV ecx, dword ptr[pDest]
91  MOV edx, dword ptr[nValNew]
92  MOV eax, dword ptr[nValComp]
93  LOCK CMPXCHG dword ptr[ecx], edx
94  }
95 #elif ! defined(_MT)
96  // this is clearly Not thread safe but lack of _MT says I don't care.
97  INT32 nValPrev = *pDest;
98  if (nValPrev == nValComp)
99  {
100  *pDest = nValNew;
101  }
102  return nValPrev;
103 #else
104 #error "No implementation of InterlockedCompareExchange"
105 #endif
106  }
107 
108  inline bool InterlockedSetIfEqual(_Inout_ INT32 VOLATILE *pDest, INT32 nValNew, INT32 nValComp) noexcept
109  {
113  return nValComp == InterlockedCompareExchange(pDest, nValNew, nValComp);
114  }
115  inline INT32 __cdecl InterlockedIncrement(INT32 VOLATILE *pDest) noexcept
116  {
117  INT32 lValNew;
118 #if defined(__GNUC__)
119  __asm__ __volatile__("lock; xaddl %0, %1"
120  : "=r" (lValNew), "=m" (*pDest)
121  : "0" (1), "m" (*pDest));
122  return(lValNew + 1);
123 #else
124  INT32 nValComp;
125  do
126  {
127  nValComp = *pDest;
128  lValNew = nValComp + 1;
129  } while (!InterlockedSetIfEqual(pDest, lValNew, nValComp));
130  return lValNew;
131 #endif
132  }
133  inline INT32 __cdecl InterlockedDecrement(INT32 VOLATILE *pDest) noexcept
134  {
135  INT32 lValNew;
136 #if defined(__GNUC__)
137  __asm__ __volatile__("lock; xaddl %0, %1"
138  : "=r" (lValNew), "=m" (*pDest)
139  : "0" (-1), "m" (*pDest));
140  return(lValNew - 1);
141 #else
142  INT32 nValComp;
143  do
144  {
145  nValComp = *pDest;
146  lValNew = nValComp - 1;
147  } while (!InterlockedSetIfEqual(pDest, lValNew, nValComp));
148  return lValNew;
149 #endif
150  }
151  inline INT32 __cdecl InterlockedExchange(INT32 VOLATILE *pDest, INT32 Value) noexcept
152  {
153  INT32 nValComp;
154  do
155  {
156  nValComp = *pDest;
157  } while (!InterlockedSetIfEqual(pDest, Value, nValComp));
158  return nValComp;
159  }
160  inline INT32 __cdecl InterlockedExchangeAdd(INT32 VOLATILE *pDest, INT32 Value) noexcept
161  {
162  INT32 nValComp;
163  do
164  {
165  nValComp = *pDest;
166  } while (!InterlockedSetIfEqual(pDest, nValComp + Value, nValComp));
167  return nValComp;
168  }
169 #endif // ! _WIN32
170 
171  //*************************************************************
172  // 64 bit values.
173 
174 #if defined(_WIN64) // (_WIN32_WINNT>=0x0502) defined(_MT) &&
175  extern "C"
176  {
179  INT64 __cdecl _InterlockedIncrement64(_Inout_ INT64 VOLATILE *pDest);
180  INT64 __cdecl _InterlockedDecrement64(_Inout_ INT64 VOLATILE *pDest);
181  INT64 __cdecl _InterlockedExchange64(_Inout_ INT64 VOLATILE *pDest, IN INT64 Value);
182  INT64 __cdecl _InterlockedExchangeAdd64(_Inout_ INT64 VOLATILE *pDest, IN INT64 Value);
183  INT64 __cdecl _InterlockedCompareExchange64(_Inout_ INT64 VOLATILE *Destination, IN INT64 ExChange, IN INT64 nValComp);
184  // #pragma intrinsic( _InterlockedIncrement64, _InterlockedDecrement64, _InterlockedExchange64, _InterlockedExchangeAdd64, _InterlockedCompareExchange64 )
185  } // "C"
186 #else
187 
188  inline INT64 __cdecl _InterlockedCompareExchange64(_Inout_ INT64 VOLATILE *pDest, IN INT64 nValNew, IN INT64 nValComp) noexcept
189  {
194 #ifdef __GNUC__
195 #ifdef USE_64BIT
196  INT64 nValPrev;
197  __asm__ __volatile__
198  (
199 #ifdef USE_64BIT
200  "lock; cmpxchgq %1,%2"
201  : "=a"(nValPrev)
202  : "q"(nValNew), "m"(*__synch_xg(pDest)), "0"(nValComp)
203  : "memory"
204 #else
205  // @todo FIND 32 bit version of this 64 bit operation !!
206  "lock; cmpxchg8b %2;"
207  : "=a"(nValPrev)
208  : "0"(nValComp), "m"(*__synch_xg(pDest)), "c"(__synch_xg(nValNew)[0]), "b"(__synch_xg(nValNew)[1])
209  : "memory", "%ebx"
210 #endif
211  );
212 #else
213  // @todo FIND 32 bit version of this 64 bit operation !!
214  INT64 nValPrev = *pDest;
215  if (nValPrev == nValComp)
216  {
217  *pDest = nValNew;
218  }
219 #endif
220  return nValPrev;
221 #elif defined(_MSC_VER) && !defined(USE_64BIT) // _MSC_VER 32 bit code for 64 bit interlock. ! USE_64BIT
222  __asm
223  {
224  lea esi, nValComp;
225  lea edi, nValNew;
226  mov eax, [esi];
227  mov edx, 4[esi];
228  mov ebx, [edi];
229  mov ecx, 4[edi];
230  mov esi, pDest;
231  // lock CMPXCHG8B [esi] is equivalent to the following except
232  // that it's atomic:
233  // ZeroFlag = (edx:eax == *esi);
234  // if (ZeroFlag) *esi = ecx:ebx;
235  // else edx:eax = *esi;
236  lock CMPXCHG8B[esi];
237  }
238 #elif ! defined(_MT)
239  // this is clearly Not thread safe but ! _MT says I don't care.
240  INT64 nValPrev = *pDest;
241  if (nValPrev == nValComp)
242  {
243  *pDest = nValNew;
244  }
245  return nValPrev;
246 #else
247 #error "No implementation of InterlockedCompareExchange64"
248 #endif
249  }
250 
251  inline bool _InterlockedSetIfEqual64(_Inout_ INT64 VOLATILE *pDest, INT64 nValNew, INT64 nValComp) noexcept
252  {
257 #if defined(_MSC_VER) && !defined(USE_64BIT) // _MSC_VER 32 bit. ! USE_64BIT
258  __asm
259  {
260  lea esi, nValComp;
261  lea edi, nValNew;
262  mov eax, [esi];
263  mov edx, 4[esi];
264  mov ebx, [edi];
265  mov ecx, 4[edi];
266  mov esi, pDest;
267  // lock CMPXCHG8B [esi] is equivalent to the following except
268  // that it's atomic:
269  // ZeroFlag = (edx:eax == *esi);
270  // if (ZeroFlag) *esi = ecx:ebx;
271  // else edx:eax = *esi;
272  lock CMPXCHG8B[esi];
273  mov eax, 0;
274  setz al;
275  }
276 #else
277  return nValComp == _InterlockedCompareExchange64(pDest, nValNew, nValComp);
278 #endif
279  }
280  inline INT64 __cdecl _InterlockedIncrement64(_Inout_ INT64 VOLATILE *pDest) noexcept
281  {
282  INT64 nValComp;
283  INT64 nValNew;
284  do
285  {
286  nValComp = *pDest;
287  nValNew = nValComp + 1;
288  } while (!_InterlockedSetIfEqual64(pDest, nValNew, nValComp));
289  return nValNew;
290  }
291  inline INT64 __cdecl _InterlockedDecrement64(_Inout_ INT64 VOLATILE *pDest) noexcept
292  {
293  INT64 nValComp;
294  INT64 nValNew;
295  do
296  {
297  nValComp = *pDest;
298  nValNew = nValComp - 1;
299  } while (!_InterlockedSetIfEqual64(pDest, nValNew, nValComp));
300  return nValNew;
301  }
302  inline INT64 __cdecl _InterlockedExchange64(_Inout_ INT64 VOLATILE *pDest, IN INT64 Value) noexcept
303  {
304  INT64 nValComp;
305  do
306  {
307  nValComp = *pDest;
308  } while (!_InterlockedSetIfEqual64(pDest, Value, nValComp));
309  return nValComp;
310  }
311  inline INT64 __cdecl _InterlockedExchangeAdd64(_Inout_ INT64 VOLATILE *pDest, IN INT64 Value) noexcept
312  {
313  INT64 nValComp;
314  do
315  {
316  nValComp = *pDest;
317  } while (!_InterlockedSetIfEqual64(pDest, nValComp + Value, nValComp));
318  return nValComp;
319  }
320 #endif // _WIN64
321 
322 #if _MSC_VER >= 1000
323 #pragma warning(default:4035)
324 #endif
325 
326  //*************************************************************
327 
328  namespace InterlockedN
329  {
337 
338  template< typename TYPE >
340  template< typename TYPE >
342  template< typename TYPE >
343  GRAYCORE_LINK TYPE ExchangeAdd(TYPE VOLATILE* pnValue, TYPE nValue) noexcept;
344  template< typename TYPE >
345  GRAYCORE_LINK TYPE Exchange(TYPE VOLATILE* pnValue, TYPE nValue) noexcept;
346  template< typename TYPE >
347  GRAYCORE_LINK TYPE CompareExchange(TYPE VOLATILE* pnValue, TYPE nValue, TYPE lComparand) noexcept;
348 
349  // Implement 32 bits as INTER32_t
350  template<> inline INTER32_t Increment<INTER32_t>(INTER32_t VOLATILE* pnValue) noexcept
351  {
352  return InterlockedIncrement(pnValue);
353  }
354  template<> inline INTER32_t Decrement<INTER32_t>(INTER32_t VOLATILE* pnValue) noexcept
355  {
356  return InterlockedDecrement(pnValue);
357  }
358  template<> inline INTER32_t ExchangeAdd<INTER32_t>(INTER32_t VOLATILE* pnValue, INTER32_t nValue) noexcept
359  {
360  return InterlockedExchangeAdd(pnValue, nValue);
361  }
362  template<> inline INTER32_t Exchange<INTER32_t>(INTER32_t VOLATILE* pnValue, INTER32_t nValue) noexcept
363  {
364  return InterlockedExchange(pnValue, nValue);
365  }
366  template<> inline INTER32_t CompareExchange<INTER32_t>(INTER32_t VOLATILE* pnValue, INTER32_t nValue, INTER32_t lComparand) noexcept
367  {
368  return InterlockedCompareExchange(pnValue, nValue, lComparand);
369  }
370 
371  // Implement 64 bit as INT64
372  template<> inline INT64 Increment<INT64>(INT64 VOLATILE* pnValue) noexcept
373  {
374  return _InterlockedIncrement64(pnValue);
375  }
376  template<> inline INT64 Decrement<INT64>(INT64 VOLATILE* pnValue) noexcept
377  {
378  return _InterlockedDecrement64(pnValue);
379  }
380  template<> inline INT64 ExchangeAdd<INT64>(INT64 VOLATILE* pnValue, INT64 nValue) noexcept
381  {
382  return _InterlockedExchangeAdd64(pnValue, nValue);
383  }
384  template<> inline INT64 Exchange<INT64>(INT64 VOLATILE* pnValue, INT64 nValue) noexcept
385  {
386  return _InterlockedExchange64(pnValue, nValue);
387  }
388  template<> inline INT64 CompareExchange<INT64>(INT64 VOLATILE* pnValue, INT64 nValue, INT64 lComparand) noexcept
389  {
390  return _InterlockedCompareExchange64(pnValue, nValue, lComparand);
391  }
392 
393  // Implement other native types as translations to above.
394 #define INTERLOCK_REMAP(T,TI) \
395  template<> inline T Increment<T>( T VOLATILE* pnValue ) noexcept \
396  { return (T) Increment<TI>( (TI VOLATILE*) pnValue); } \
397  template<> inline T Decrement<T>( T VOLATILE* pnValue ) noexcept \
398  { return (T) Decrement<TI>( (TI VOLATILE*) pnValue); } \
399  template<> inline T ExchangeAdd<T>( T VOLATILE* pnValue, T nValue ) noexcept \
400  { return (T) ExchangeAdd<TI>( (TI VOLATILE*) pnValue, (TI) nValue ); } \
401  template<> inline T Exchange<T>( T VOLATILE* pnValue, T nValue ) noexcept \
402  { return (T) Exchange<TI>( (TI VOLATILE*) pnValue,(TI)nValue); } \
403  template<> inline T CompareExchange<T>( T VOLATILE* pnValue, T nValue, T lComparand ) noexcept \
404  { return (T) CompareExchange<TI>( (TI VOLATILE*) pnValue, (TI)nValue, (TI)lComparand); }
405 
407  INTERLOCK_REMAP(UINT64, INT64);
408 
409  // Special fix ups for the use of long vs int.
410 
411 #ifdef _WIN32
412  INTERLOCK_REMAP(int, INTER32_t); // _WIN32 always uses LONG for 32 bits.
413  INTERLOCK_REMAP(ULONG, INTER32_t);
414 #else
415 #if ! defined(USE_INT64)
416  INTERLOCK_REMAP(long, INTER32_t); // GNU 32 bit.
417  INTERLOCK_REMAP(ULONG, INTER32_t);
418 #else
419  // GNU 64 bit long is 64 bit. has no other _int64 intrinsic type.
420 #endif
421 #endif
422  };
423 
424  //*************************************************************
425 
426  template< typename TYPE = INTER32_t > // INTER32_t = 32 bit, INT64 for 64 bit.
428  {
434 
436 
437  protected:
439 
440  public:
441  cInterlockedVal(TYPE nValue = 0) noexcept
442  : m_nValue(nValue)
443  {
444  ASSERT((((UINT_PTR)&m_nValue) % sizeof(TYPE)) == 0); // must be aligned!!
445  }
446 
447  TYPE Inc() noexcept
448  {
449  return InterlockedN::Increment(&m_nValue);
450  }
451  void IncV() noexcept
452  {
453  InterlockedN::Increment(&m_nValue);
454  }
455  TYPE Dec() noexcept
456  {
457  return InterlockedN::Decrement(&m_nValue);
458  }
459  void DecV() noexcept
460  {
461  InterlockedN::Decrement(&m_nValue);
462  }
463 
464  TYPE AddX(TYPE nValue) noexcept
465  {
467  return InterlockedN::ExchangeAdd(&m_nValue, nValue);
468  }
469  TYPE Exchange(TYPE nValue) noexcept
470  {
471  return InterlockedN::Exchange(&m_nValue, nValue);
472  }
473 
474  TYPE CompareExchange(TYPE nValue, TYPE lComparand = 0) noexcept
475  {
478  return InterlockedN::CompareExchange(&m_nValue, nValue, lComparand);
479  }
480  bool SetIfEqual(TYPE nValue, TYPE lComparand = 0) noexcept
481  {
482  return(lComparand == CompareExchange(nValue, lComparand));
483  }
484 
485  inline TYPE operator ++() noexcept
486  {
488  return Inc();
489  }
490  inline TYPE operator --() noexcept
491  {
493  return Dec();
494  }
495  TYPE get_Value() const noexcept
496  {
497  return m_nValue;
498  }
499  void put_Value(TYPE nVal) noexcept
500  {
501  m_nValue = nVal;
502  }
503  operator TYPE () const noexcept
504  {
505  return m_nValue;
506  }
507  const THIS_t& operator = (TYPE nValNew) noexcept
508  {
509  Exchange(nValNew);
510  return *this;
511  }
512  };
513 
514  // Base types=INT32, INT64. Derived types=UINT32,UINT64
515 
516  typedef __DECL_ALIGN(4) cInterlockedVal<INT32> cInterlockedInt32;
517  typedef __DECL_ALIGN(4) cInterlockedVal<UINT32> cInterlockedUInt32;
518 
519  typedef __DECL_ALIGN(8) cInterlockedVal<INT64> cInterlockedInt64;
520  typedef __DECL_ALIGN(8) cInterlockedVal<UINT64> cInterlockedUInt64;
521 
522  typedef __DECL_ALIGN(_SIZEOF_INT) cInterlockedVal<int> cInterlockedInt; // default int type. whatever that is.
523  typedef __DECL_ALIGN(_SIZEOF_INT) cInterlockedVal<UINT> cInterlockedUInt;
524 
525  typedef __DECL_ALIGN(_SIZEOF_LONG) cInterlockedVal<long> cInterlockedLong;
526  typedef __DECL_ALIGN(_SIZEOF_LONG) cInterlockedVal<ULONG> cInterlockedULong;
527 
528  typedef __DECL_ALIGN(_SIZEOF_PTR) cInterlockedVal<INT_PTR> cInterlockedIntPtr; // int that can also hold a pointer.
529 
530  //*****************************************************
531 
532  template< typename TYPE = void > // INT_PTR = INT32 for 32 bit, INT64 for 64 bit.
533  class GRAYCORE_LINK __DECL_ALIGN(_SIZEOF_PTR) cInterlockedPtr : protected cInterlockedVal < INT_PTR >
534  {
538 
539  public:
540  cInterlockedPtr(TYPE* pVal) noexcept : cInterlockedVal<INT_PTR>((INT_PTR)pVal)
541  {
542  }
543  operator TYPE* () noexcept
544  {
545  return (TYPE*)(this->m_nValue);
546  }
547  operator const TYPE* () const noexcept
548  {
549  return (const TYPE*)(this->m_nValue);
550  }
551 
552  const cInterlockedPtr<TYPE>& operator = (TYPE* pValNew)
553  {
554  // InterlockedExchangePointer()
555  this->Exchange((INT_PTR)pValNew);
556  return *this;
557  }
558  };
559 
560  typedef cInterlockedPtr<> cInterlockedPtrV; // void pointer.
561 
562  //*****************************************************
563 
565  {
569 
570  private:
571  cInterlockedInt& m_rCount;
572  int m_nCount;
573  public:
574  cInterlockedInc(cInterlockedInt& count) noexcept
575  : m_rCount(count)
576  , m_nCount(count.Inc())
577  {
578  }
579  ~cInterlockedInc() noexcept
580  {
581  m_rCount.Dec();
582  }
583 
584  int get_Count() const noexcept
585  {
586  return m_nCount;
587  }
588 
590  };
591 
592 #ifdef GRAY_DLL // force implementation/instantiate for DLL/SO.
596 #endif
597 
598 }
599 
600 #endif // _INC_cInterlockedVal_H
#define GRAYCORE_LINK
Definition: GrayCore.h:47
#define _SIZEOF_PTR
bytes = sizeof(void*) for __DECL_ALIGN macro. Can't do sizeof(x). uintptr_t
Definition: Index.h:22
#define TYPE
Definition: StrT.cpp:38
#define VOLATILE
Definition: SysTypes.h:429
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define _SIZEOF_LONG
Definition: cInterlockedVal.h:24
#define _SIZEOF_INT
Definition: cInterlockedVal.h:20
#define INTERLOCK_REMAP(T, TI)
Definition: cInterlockedVal.h:394
#define __synch_xg(x)
Definition: cInterlockedVal.h:47
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
Definition: cInterlockedVal.h:565
cInterlockedInc(cInterlockedInt &count) noexcept
Definition: cInterlockedVal.h:574
int get_Count() const noexcept
Definition: cInterlockedVal.h:584
~cInterlockedInc() noexcept
Definition: cInterlockedVal.h:579
Definition: cInterlockedVal.h:428
bool SetIfEqual(TYPE nValue, TYPE lComparand=0) noexcept
Definition: cInterlockedVal.h:480
TYPE CompareExchange(TYPE nValue, TYPE lComparand=0) noexcept
Definition: cInterlockedVal.h:474
TYPE AddX(TYPE nValue) noexcept
Definition: cInterlockedVal.h:464
void IncV() noexcept
Definition: cInterlockedVal.h:451
TYPE Exchange(TYPE nValue) noexcept
Definition: cInterlockedVal.h:469
void DecV() noexcept
Definition: cInterlockedVal.h:459
void put_Value(TYPE nVal) noexcept
Definition: cInterlockedVal.h:499
cInterlockedVal(TYPE nValue=0) noexcept
Definition: cInterlockedVal.h:441
TYPE get_Value() const noexcept
Definition: cInterlockedVal.h:495
TYPE Inc() noexcept
Definition: cInterlockedVal.h:447
TYPE volatile m_nValue
This MUST be sizeof(TYPE) aligned?! __DECL_ALIGN(sizeof(TYPE)).
Definition: cInterlockedVal.h:438
TYPE Dec() noexcept
Definition: cInterlockedVal.h:455
INTER32_t CompareExchange< INTER32_t >(INTER32_t volatile *pnValue, INTER32_t nValue, INTER32_t lComparand) noexcept
Definition: cInterlockedVal.h:366
INT64 Decrement< INT64 >(INT64 volatile *pnValue) noexcept
Definition: cInterlockedVal.h:376
__DECL_IMPORT TYPE Decrement(TYPE volatile *pnValue) noexcept
__DECL_IMPORT TYPE Increment(TYPE volatile *pnValue) noexcept
INTER32_t Decrement< INTER32_t >(INTER32_t volatile *pnValue) noexcept
Definition: cInterlockedVal.h:354
INT64 Exchange< INT64 >(INT64 volatile *pnValue, INT64 nValue) noexcept
Definition: cInterlockedVal.h:384
__DECL_IMPORT TYPE ExchangeAdd(TYPE volatile *pnValue, TYPE nValue) noexcept
INTER32_t Exchange< INTER32_t >(INTER32_t volatile *pnValue, INTER32_t nValue) noexcept
Definition: cInterlockedVal.h:362
INT64 ExchangeAdd< INT64 >(INT64 volatile *pnValue, INT64 nValue) noexcept
Definition: cInterlockedVal.h:380
INTER32_t Increment< INTER32_t >(INTER32_t volatile *pnValue) noexcept
Definition: cInterlockedVal.h:350
__DECL_IMPORT TYPE Exchange(TYPE volatile *pnValue, TYPE nValue) noexcept
INT64 Increment< INT64 >(INT64 volatile *pnValue) noexcept
Definition: cInterlockedVal.h:372
__DECL_IMPORT TYPE CompareExchange(TYPE volatile *pnValue, TYPE nValue, TYPE lComparand) noexcept
INTER32_t ExchangeAdd< INTER32_t >(INTER32_t volatile *pnValue, INTER32_t nValue) noexcept
Definition: cInterlockedVal.h:358
INT64 CompareExchange< INT64 >(INT64 volatile *pnValue, INT64 nValue, INT64 lComparand) noexcept
Definition: cInterlockedVal.h:388
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
INT64 __cdecl _InterlockedExchange64(_Inout_ INT64 volatile *pDest, IN INT64 Value) noexcept
Definition: cInterlockedVal.h:302
INT32 INTER32_t
Interlock intrinsic type as INT32.
Definition: cInterlockedVal.h:44
INT64 __cdecl _InterlockedCompareExchange64(_Inout_ INT64 volatile *pDest, IN INT64 nValNew, IN INT64 nValComp) noexcept
Definition: cInterlockedVal.h:188
class __DECL_IMPORT __DECL_ALIGN(4) cInterlockedPtr typedef cInterlockedPtr cInterlockedPtrV
Definition: cInterlockedVal.h:533
INT64 __cdecl _InterlockedExchangeAdd64(_Inout_ INT64 volatile *pDest, IN INT64 Value) noexcept
Definition: cInterlockedVal.h:311
INT32 __cdecl InterlockedExchangeAdd(INT32 volatile *pDest, INT32 Value) noexcept
Definition: cInterlockedVal.h:160
typedef __DECL_ALIGN(4) cInterlockedVal< INT32 > cInterlockedInt32
INT32 __cdecl InterlockedDecrement(INT32 volatile *pDest) noexcept
Definition: cInterlockedVal.h:133
INT32 __cdecl InterlockedCompareExchange(INT32 volatile *pDest, INT32 nValNew, INT32 nValComp) noexcept
Definition: cInterlockedVal.h:49
bool InterlockedSetIfEqual(_Inout_ INT32 volatile *pDest, INT32 nValNew, INT32 nValComp) noexcept
Definition: cInterlockedVal.h:108
template class __DECL_IMPORT cInterlockedPtr< >
Definition: cInterlockedVal.h:593
INT32 __cdecl InterlockedIncrement(INT32 volatile *pDest) noexcept
Definition: cInterlockedVal.h:115
bool _InterlockedSetIfEqual64(_Inout_ INT64 volatile *pDest, INT64 nValNew, INT64 nValComp) noexcept
Definition: cInterlockedVal.h:251
INT64 __cdecl _InterlockedDecrement64(_Inout_ INT64 volatile *pDest) noexcept
Definition: cInterlockedVal.h:291
INT64 __cdecl _InterlockedIncrement64(_Inout_ INT64 volatile *pDest) noexcept
Definition: cInterlockedVal.h:280
INT32 __cdecl InterlockedExchange(INT32 volatile *pDest, INT32 Value) noexcept
Definition: cInterlockedVal.h:151
Definition: cInterlockedVal.h:46
INT32 a[4]
Definition: cInterlockedVal.h:46