Changeset: 819615f16909 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=819615f16909
Modified Files:
        gdk/gdk_atomic.h
Branch: default
Log Message:

Introduce ATOMIC_CAS (compare and set) macro/function.


diffs (98 lines):

diff --git a/gdk/gdk_atomic.h b/gdk/gdk_atomic.h
--- a/gdk/gdk_atomic.h
+++ b/gdk/gdk_atomic.h
@@ -17,6 +17,7 @@
  * ATOMIC_GET -- return the value of a variable;
  * ATOMIC_SET -- set the value of a variable;
  * ATOMIC_XCG -- set the value of a variable, return original value;
+ * ATOMIC_CAS -- compare-and-set (see below)
  * ATOMIC_ADD -- add a value to a variable, return original value;
  * ATOMIC_SUB -- subtract a value from a variable, return original value;
  * ATOMIC_INC -- increment a variable's value, return new value;
@@ -24,6 +25,12 @@
  * These interfaces work on variables of type ATOMIC_TYPE
  * (int or int64_t depending on architecture).
  *
+ * The compare-and-set operation is based on the C11 standard: if the
+ * atomic variable equals the expected value, the atomic variable is
+ * replaced by the desired value and true is returned.  Otherwise, the
+ * expected value is replaced by the current value of the atomic
+ * variable and false is returned.
+ *
  * Some of these are also available for pointers:
  * ATOMIC_PTR_INIT
  * ATOMIC_GET_PTR
@@ -79,6 +86,7 @@ typedef unsigned long long ATOMIC_BASE_T
 #define ATOMIC_GET(var)                atomic_load(var)
 #define ATOMIC_SET(var, val)   atomic_store(var, (ATOMIC_BASE_TYPE) (val))
 #define ATOMIC_XCG(var, val)   atomic_exchange(var, (ATOMIC_BASE_TYPE) (val))
+#define ATOMIC_CAS(var, exp, des)      atomic_compare_exchange_strong(var, 
exp, (ATOMIC_BASE_TYPE) (des))
 #define ATOMIC_ADD(var, val)   atomic_fetch_add(var, (ATOMIC_BASE_TYPE) (val))
 #define ATOMIC_SUB(var, val)   atomic_fetch_sub(var, (ATOMIC_BASE_TYPE) (val))
 #define ATOMIC_INC(var)                (atomic_fetch_add(var, 1) + 1)
@@ -129,6 +137,16 @@ typedef int64_t ATOMIC_BASE_TYPE;
 #endif
 #define ATOMIC_SET(var, val)   _InterlockedExchange64(var, (ATOMIC_BASE_TYPE) 
(val))
 #define ATOMIC_XCG(var, val)   _InterlockedExchange64(var, (ATOMIC_BASE_TYPE) 
(val))
+static inline bool
+ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE *exp, ATOMIC_BASE_TYPE des)
+{
+       ATOMIC_BASE_TYPE old;
+       old = _InterlockedCompareExchange64(var, des, *exp);
+       if (old == *exp)
+               return true;
+       *exp = old;
+       return false;
+}
 #define ATOMIC_ADD(var, val)   _InterlockedExchangeAdd64(var, 
(ATOMIC_BASE_TYPE) (val))
 #define ATOMIC_SUB(var, val)   _InterlockedExchangeAdd64(var, 
-(ATOMIC_BASE_TYPE) (val))
 #define ATOMIC_INC(var)                _InterlockedIncrement64(var)
@@ -155,6 +173,16 @@ typedef int ATOMIC_BASE_TYPE;
 #endif
 #define ATOMIC_SET(var, val)   _InterlockedExchange(var, (ATOMIC_BASE_TYPE) 
(val))
 #define ATOMIC_XCG(var, val)   _InterlockedExchange(var, (ATOMIC_BASE_TYPE) 
(val))
+static inline bool
+ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE *exp, ATOMIC_BASE_TYPE des)
+{
+       ATOMIC_BASE_TYPE old;
+       old = _InterlockedCompareExchange(var, des, *exp);
+       if (old == *exp)
+               return true;
+       *exp = old;
+       return false;
+}
 #define ATOMIC_ADD(var, val)   _InterlockedExchangeAdd(var, (ATOMIC_BASE_TYPE) 
(val))
 #define ATOMIC_SUB(var, val)   _InterlockedExchangeAdd(var, 
-(ATOMIC_BASE_TYPE) (val))
 #define ATOMIC_INC(var)                _InterlockedIncrement(var)
@@ -195,6 +223,7 @@ typedef int ATOMIC_TYPE;
 #define ATOMIC_GET(var)                __atomic_load_n(var, __ATOMIC_SEQ_CST)
 #define ATOMIC_SET(var, val)   __atomic_store_n(var, (ATOMIC_TYPE) (val), 
__ATOMIC_SEQ_CST)
 #define ATOMIC_XCG(var, val)   __atomic_exchange_n(var, (ATOMIC_TYPE) (val), 
__ATOMIC_SEQ_CST
+#define ATOMIC_CAS(var, exp, des)      __atomic_compare_exchange_n(var, exp, 
(ATOMIC_TYPE) (des), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
 #define ATOMIC_ADD(var, val)   __atomic_fetch_add(var, (ATOMIC_TYPE) (val), 
__ATOMIC_SEQ_CST)
 #define ATOMIC_SUB(var, val)   __atomic_fetch_sub(var, (ATOMIC_TYPE) (val), 
__ATOMIC_SEQ_CST)
 #define ATOMIC_INC(var)                __atomic_add_fetch(var, 1, 
__ATOMIC_SEQ_CST)
@@ -260,6 +289,23 @@ ATOMIC_XCG(ATOMIC_TYPE *var, ATOMIC_BASE
 }
 #define ATOMIC_XCG(var, val)   ATOMIC_XCG(var, (ATOMIC_BASE_TYPE) (val))
 
+static inline bool
+ATOMIC_CAS(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE *exp, ATOMIC_BASE_TYPE des)
+{
+       bool ret;
+       pthread_mutex_lock(&var->lck);
+       if (var->val == *exp) {
+               var->val = des;
+               ret = true;
+       } else {
+               *exp = var->val;
+               ret = false;
+       }
+       pthread_mutex_unlock(&var->lck);
+       return ret;
+}
+#define ATOMIC_CAS(var, exp, des)      ATOMIC_CAS(var, exp, (ATOMIC_BASE_TYPE) 
(des))
+
 static inline ATOMIC_BASE_TYPE
 ATOMIC_ADD(ATOMIC_TYPE *var, ATOMIC_BASE_TYPE val)
 {
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to