Add infrastructure for reference counts.
OpenSSL has traditionally done reference counting with |int|s and the
|CRYPTO_add| function. Unless a special callback is installed (rare),
this is implemented by doing the reference count operations under a
lock.
This change adds infrastructure for handling reference counts and uses
atomic operations when C11 support is available.
Change-Id: Ia023ce432319efd00f77a7340da27d16ee4b63c3
Reviewed-on: https://boringssl-review.googlesource.com/4771
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/internal.h b/crypto/internal.h
index 42125db..2a11ab5 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -354,6 +354,32 @@
OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void));
+/* Reference counting. */
+
+#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
+#define OPENSSL_C11_ATOMIC
+#endif
+
+/* CRYPTO_REFCOUNT_MAX is the value at which the reference count saturates. */
+#define CRYPTO_REFCOUNT_MAX 0xffffffff
+
+/* CRYPTO_refcount_inc atomically increments the value at |*count| unless the
+ * value would overflow. It's safe for multiple threads to concurrently call
+ * this or |CRYPTO_refcount_dec_and_test_zero| on the same
+ * |CRYPTO_refcount_t|. */
+OPENSSL_EXPORT void CRYPTO_refcount_inc(CRYPTO_refcount_t *count);
+
+/* CRYPTO_refcount_dec_and_test_zero tests the value at |*count|:
+ * if it's zero, it crashes the address space.
+ * if it's the maximum value, it returns zero.
+ * otherwise, it atomically decrements it and returns one iff the resulting
+ * value is zero.
+ *
+ * It's safe for multiple threads to concurrently call this or
+ * |CRYPTO_refcount_inc| on the same |CRYPTO_refcount_t|. */
+OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
+
+
/* Locks.
*
* Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in