FARGOS/VISTA Object Management Environment Core  ..
FARGOS/VISTA Object Management Environment Core Table of Contents
atomic_values.h
Go to the documentation of this file.
1 #ifndef _ATOMIC_VALUES_H_
2 #define _ATOMIC_VALUES_H_ "$Id: atomic_values.h 454 2020-07-23 20:22:23Z geoff $"
4 
6 /* Copyright (C) 2010 - 2019 FARGOS Development, LLC */
7 
26 #ifdef _MSC_VER /* compiled by Microsoft Visual Studio */
27 
28 #include <winsock2.h>
29 #include <Windows.h>
30 #endif
31 #include <stdint.h>
33 
34 #if __GNUC__
35 
37 #define DEFINE_COMPARE_AND_SWAP_TYPE(suffix, typeName) inline typeName compareAndSwap_ ## suffix (typeName *loc, typeName oldVal, typeName newVal) { \
38  typeName result = __sync_val_compare_and_swap(loc, oldVal, newVal); \
39  return (result); \
40 }
41 
45 #define DEFINE_DID_COMPARE_AND_SWAP_TYPE(suffix, typeName) inline bool did_compareAndSwap_ ## suffix (typeName *loc, typeName oldVal, typeName newVal) { \
46  bool result = __sync_bool_compare_and_swap(loc, oldVal, newVal); \
47  return (result); \
48 }
49 #endif /* __GNUC__ */
50 
53 #define DEFINE_ATOMIC_INCREMENT_TYPE(suffix, typeName) inline typeName atomicIncrement_ ## suffix(typeName *loc, int32_t amount) { typeName newVal; \
54  bool ok; do { typeName cur = *(loc); newVal = cur + (amount); \
55  ok = did_compareAndSwap_ ## suffix (loc, cur, newVal); \
56  } while (ok == false); \
57  return (newVal); \
58 }
59 
60 #if _MSC_VER /* compiled by Microsoft Visual Studio */
61 
62 inline void *compareAndSwap_Pointer(void **loc, void *oldVal, void *newVal) {
63  void *orig = InterlockedCompareExchangePointer(loc, newVal, oldVal);
64  return (orig);
65 }
66 
67 inline bool did_compareAndSwap_Pointer(void **loc, void *oldVal, void *newVal) {
68  void *orig = InterlockedCompareExchangePointer(loc, newVal, oldVal);
69  return (orig == oldVal);
70 }
71 
72 inline uint32_t compareAndSwap_uint32(uint32_t *loc, uint32_t oldVal, uint32_t newVal) {
73  uint32_t orig = InterlockedCompareExchange(loc, newVal, oldVal);
74  return (orig);
75 }
76 
77 inline bool did_compareAndSwap_uint32(uint32_t *loc, uint32_t oldVal, uint32_t newVal) {
78  uint32_t orig = InterlockedCompareExchange(loc, newVal, oldVal);
79  return (orig == oldVal);
80 }
81 
82 inline uint64_t compareAndSwap_uint64(uint64_t *loc, uint64_t oldVal, uint64_t newVal) {
83  uint64_t orig = InterlockedCompareExchange64((int64_t *) loc, (int64_t) newVal, (int64_t) oldVal);
84  return (orig);
85 }
86 
87 inline bool did_compareAndSwap_uint64(uint64_t *loc, uint64_t oldVal, uint64_t newVal) {
88  uint64_t orig = InterlockedCompareExchange64((int64_t *) loc, newVal, oldVal);
89  return (orig == oldVal);
90 }
91 
92 DEFINE_ATOMIC_INCREMENT_TYPE(uint32, uint32_t);
93 DEFINE_ATOMIC_INCREMENT_TYPE(uint64, uint64_t);
94 
95 #ifdef __cplusplus
96 template <NUMTYPE> incrementAtomically(NUMTYPE *loc, NUMTYPE amt)
97 {
98  NUMTYPE newVal;
99  bool ok;
100  do {
101  NUMTYPE cur = *(loc);
102  newVal = cur + (amount);
103  if ((typeid(NUMTYPE) == typeid(int32_t) || (typeid(NUMTYPE) == typeid(uint32_t)) {
104  NUMTYPE orig = InterlockedCompareExchange((uint32_t), newVal, cur);
105  ok = orig == cur;
106  } else if ((typeid(NUMTYPE) == typeid(int64_t)) || (typeid(NUMTYPE) == typeid(uint64_t))) {
107  NUMTYPE orig = InterlockedCompareExchange64((uint64_t), newVal, cur);
108  ok = orig == cur;
109  }
110  } while (ok == false);
111  return (newVal);
112 }
113 #endif
114 
115 
116 #endif /* _MSC_VER */
117 
118 #ifdef __GNUC__
119 DEFINE_COMPARE_AND_SWAP_TYPE(Pointer, void *);
120 DEFINE_DID_COMPARE_AND_SWAP_TYPE(Pointer, void *);
121 
122 DEFINE_COMPARE_AND_SWAP_TYPE(uint32, uint32_t);
123 DEFINE_DID_COMPARE_AND_SWAP_TYPE(uint32, uint32_t);
124 
125 DEFINE_COMPARE_AND_SWAP_TYPE(uint64, uint64_t);
126 DEFINE_DID_COMPARE_AND_SWAP_TYPE(uint64, uint64_t);
127 
128 DEFINE_ATOMIC_INCREMENT_TYPE(uint32, uint32_t);
129 DEFINE_ATOMIC_INCREMENT_TYPE(uint64, uint64_t);
130 
131 #if 0
132 inline void *compareAndSwapPointer(void **location, void *oldVal, void *newVal) {
133  void *result = __sync_val_compare_and_swap(location, oldVal, newVal);
134  return (result);
135 }
136 #endif
137 
138 #ifdef __cplusplus
139 template <typename NUMTYPE> NUMTYPE incrementAtomically(NUMTYPE *loc, NUMTYPE amount)
140 {
141  NUMTYPE newVal;
142  bool ok;
143  do {
144  NUMTYPE cur = *(loc);
145  newVal = cur + (amount);
146  ok = __sync_bool_compare_and_swap(loc, cur, newVal);
147  } while (ok == false);
148  return (newVal);
149 }
150 
154 #endif
155 #endif /* __GNUC__ */
156 
157 #endif
158 
159 /* vim: set expandtab shiftwidth=4 tabstop=4: */
DEFINE_DID_COMPARE_AND_SWAP_TYPE
#define DEFINE_DID_COMPARE_AND_SWAP_TYPE(suffix, typeName)
Implement an inline compare-and-swap routine for a distinct native type, but return a Boolean indicat...
Definition: atomic_values.h:45
DEFINE_ATOMIC_INCREMENT_TYPE
#define DEFINE_ATOMIC_INCREMENT_TYPE(suffix, typeName)
Implement an atomic increment operator for a native type.
Definition: atomic_values.h:53
incrementAtomically
NUMTYPE incrementAtomically(NUMTYPE *loc, NUMTYPE amount)
Definition: atomic_values.h:139
compiler_hints.h
Compiler-specific macros to provide performance-related hints.
DEFINE_COMPARE_AND_SWAP_TYPE
#define DEFINE_COMPARE_AND_SWAP_TYPE(suffix, typeName)
Implement an inline compare-and-swap routine for a particular type.
Definition: atomic_values.h:37
Generated: Tue Jul 28 2020 16:03:24
Support Information