utils: Add ref_cur() to retrieve the current value of a reference counter
authorTobias Brunner <tobias@strongswan.org>
Fri, 11 Apr 2014 13:13:22 +0000 (15:13 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 24 Apr 2014 15:53:42 +0000 (17:53 +0200)
On many architectures it is safe to read the value directly (those
using cache coherency protocols, and with atomic loads for 32-bit
values) but it is not if that's not the case or if we ever decide to
make refcount_t 64-bit (load not atomic on x86).

So make sure the operation is actually atomic and that users do not
have to care about the size of refcount_t.

src/libstrongswan/utils/utils.c
src/libstrongswan/utils/utils.h

index fe80edb..e4da6dd 100644 (file)
@@ -528,7 +528,6 @@ refcount_t ref_get(refcount_t *ref)
        pthread_mutex_lock(&ref_mutex);
        current = ++(*ref);
        pthread_mutex_unlock(&ref_mutex);
-
        return current;
 }
 
@@ -546,6 +545,19 @@ bool ref_put(refcount_t *ref)
 }
 
 /**
+ * Current refcount
+ */
+refcount_t ref_cur(refcount_t *ref)
+{
+       refcount_t current;
+
+       pthread_mutex_lock(&ref_mutex);
+       current = *ref;
+       pthread_mutex_unlock(&ref_mutex);
+       return current;
+}
+
+/**
  * Single mutex for all compare and swap operations.
  */
 static pthread_mutex_t cas_mutex = PTHREAD_MUTEX_INITIALIZER;
index a55e7d8..4b29903 100644 (file)
@@ -752,6 +752,7 @@ typedef u_int refcount_t;
 
 #define ref_get(ref) __sync_add_and_fetch(ref, 1)
 #define ref_put(ref) (!__sync_sub_and_fetch(ref, 1))
+#define ref_cur(ref) __sync_fetch_and_add(ref, 0)
 
 #define cas_bool(ptr, oldval, newval) \
                                        (__sync_bool_compare_and_swap(ptr, oldval, newval))
@@ -763,7 +764,7 @@ typedef u_int refcount_t;
 /**
  * Get a new reference.
  *
- * Increments the reference counter atomic.
+ * Increments the reference counter atomically.
  *
  * @param ref  pointer to ref counter
  * @return             new value of ref
@@ -773,7 +774,7 @@ refcount_t ref_get(refcount_t *ref);
 /**
  * Put back a unused reference.
  *
- * Decrements the reference counter atomic and
+ * Decrements the reference counter atomically and
  * says if more references available.
  *
  * @param ref  pointer to ref counter
@@ -782,6 +783,14 @@ refcount_t ref_get(refcount_t *ref);
 bool ref_put(refcount_t *ref);
 
 /**
+ * Get the current value of the reference counter.
+ *
+ * @param ref  pointer to ref counter
+ * @return             current value of ref
+ */
+refcount_t ref_cur(refcount_t *ref);
+
+/**
  * Atomically replace value of ptr with newval if it currently equals oldval.
  *
  * @param ptr          pointer to variable