Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/external/mpl/bind/dist/lib/isc/include/isc/refcount.h,v rcsdiff: /ftp/cvs/cvsroot/src/external/mpl/bind/dist/lib/isc/include/isc/refcount.h,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.1.1.1 retrieving revision 1.1.1.2 diff -u -p -r1.1.1.1 -r1.1.1.2 --- src/external/mpl/bind/dist/lib/isc/include/isc/refcount.h 2018/08/12 12:08:26 1.1.1.1 +++ src/external/mpl/bind/dist/lib/isc/include/isc/refcount.h 2019/01/09 16:48:19 1.1.1.2 @@ -1,4 +1,4 @@ -/* $NetBSD: refcount.h,v 1.1.1.1 2018/08/12 12:08:26 christos Exp $ */ +/* $NetBSD: refcount.h,v 1.1.1.2 2019/01/09 16:48:19 christos Exp $ */ /* * Copyright (C) Internet Systems Consortium, Inc. ("ISC") @@ -11,9 +11,9 @@ * information regarding copyright ownership. */ +#pragma once -#ifndef ISC_REFCOUNT_H -#define ISC_REFCOUNT_H 1 +#include #include #include @@ -23,278 +23,70 @@ #include #include -#if defined(ISC_PLATFORM_HAVESTDATOMIC) -#include -#endif - /*! \file isc/refcount.h * \brief Implements a locked reference counter. * - * These functions may actually be - * implemented using macros, and implementations of these macros are below. - * The isc_refcount_t type should not be accessed directly, as its contents - * depend on the implementation. + * These macros uses C11(-like) atomic functions to implement reference + * counting. The isc_refcount_t type must not be accessed directly. */ ISC_LANG_BEGINDECLS -/* - * Function prototypes - */ +typedef atomic_uint_fast32_t isc_refcount_t; -/* - * isc_result_t - * isc_refcount_init(isc_refcount_t *ref, unsigned int n); - * - * Initialize the reference counter. There will be 'n' initial references. +/** \def isc_refcount_init(ref, n) + * \brief Initialize the reference counter. + * \param[in] ref pointer to reference counter. + * \param[in] n an initial number of references. + * \return nothing. * - * Requires: - * ref != NULL + * \warning No memory barrier are being imposed here. */ +#define isc_refcount_init(target, value) \ + atomic_init(target, value) -/* - * void - * isc_refcount_destroy(isc_refcount_t *ref); +/** \def isc_refcount_current(ref) + * \brief Returns current number of references. + * \param[in] ref pointer to reference counter. + * \returns current value of reference counter. * - * Destroys a reference counter. - * - * Requires: - * ref != NULL - * The number of references is 0. + * Undo implict promotion to 64 bits in our Windows implementation of + * atomic_load_explicit() by casting to uint_fast32_t. */ -/* - * void - * isc_refcount_increment(isc_refcount_t *ref, unsigned int *targetp); - * isc_refcount_increment0(isc_refcount_t *ref, unsigned int *targetp); - * - * Increments the reference count, returning the new value in targetp if it's - * not NULL. The reference counter typically begins with the initial counter - * of 1, and will be destroyed once the counter reaches 0. Thus, - * isc_refcount_increment() additionally requires the previous counter be - * larger than 0 so that an error which violates the usage can be easily - * caught. isc_refcount_increment0() does not have this restriction. - * - * Requires: - * ref != NULL. - */ +#define isc_refcount_current(target) \ + (uint_fast32_t)atomic_load_explicit(target, memory_order_acquire) -/* - * void - * isc_refcount_decrement(isc_refcount_t *ref, unsigned int *targetp); - * - * Decrements the reference count, returning the new value in targetp if it's - * not NULL. - * - * Requires: - * ref != NULL. +/** \def isc_refcount_destroy(ref) + * \brief a destructor that makes sure that all references were cleared. + * \param[in] ref pointer to reference counter. + * \returns nothing. */ +#define isc_refcount_destroy(target) \ + ISC_REQUIRE(isc_refcount_current(target) == 0) - -/* - * Sample implementations +/** \def isc_refcount_increment0(ref) + * \brief increases reference counter by 1. + * \param[in] ref pointer to reference counter. + * \returns previous value of reference counter. */ -#ifdef ISC_PLATFORM_USETHREADS -#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || defined(ISC_PLATFORM_HAVEXADD) -#define ISC_REFCOUNT_HAVEATOMIC 1 -#if (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) -#define ISC_REFCOUNT_HAVESTDATOMIC 1 -#endif - -typedef struct isc_refcount { -#if defined(ISC_REFCOUNT_HAVESTDATOMIC) - atomic_int_fast32_t refs; -#else - isc_int32_t refs; -#endif -} isc_refcount_t; - -#if defined(ISC_REFCOUNT_HAVESTDATOMIC) - -#define isc_refcount_current(rp) \ - ((unsigned int)(atomic_load_explicit(&(rp)->refs, \ - memory_order_relaxed))) -#define isc_refcount_destroy(rp) ISC_REQUIRE(isc_refcount_current(rp) == 0) - -#define isc_refcount_increment0(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - isc_int32_t prev; \ - prev = atomic_fetch_add_explicit \ - (&(rp)->refs, 1, memory_order_relaxed); \ - if (_tmp != NULL) \ - *_tmp = prev + 1; \ - } while (0) - -#define isc_refcount_increment(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - isc_int32_t prev; \ - prev = atomic_fetch_add_explicit \ - (&(rp)->refs, 1, memory_order_relaxed); \ - ISC_REQUIRE(prev > 0); \ - if (_tmp != NULL) \ - *_tmp = prev + 1; \ - } while (0) - -#define isc_refcount_decrement(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - isc_int32_t prev; \ - prev = atomic_fetch_sub_explicit \ - (&(rp)->refs, 1, memory_order_relaxed); \ - ISC_REQUIRE(prev > 0); \ - if (_tmp != NULL) \ - *_tmp = prev - 1; \ - } while (0) - -#else /* ISC_REFCOUNT_HAVESTDATOMIC */ - -#define isc_refcount_current(rp) \ - ((unsigned int)(isc_atomic_xadd(&(rp)->refs, 0))) -#define isc_refcount_destroy(rp) ISC_REQUIRE(isc_refcount_current(rp) == 0) - -#define isc_refcount_increment0(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - isc_int32_t prev; \ - prev = isc_atomic_xadd(&(rp)->refs, 1); \ - if (_tmp != NULL) \ - *_tmp = prev + 1; \ - } while (0) - -#define isc_refcount_increment(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - isc_int32_t prev; \ - prev = isc_atomic_xadd(&(rp)->refs, 1); \ - ISC_REQUIRE(prev > 0); \ - if (_tmp != NULL) \ - *_tmp = prev + 1; \ - } while (0) - -#define isc_refcount_decrement(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - isc_int32_t prev; \ - prev = isc_atomic_xadd(&(rp)->refs, -1); \ - ISC_REQUIRE(prev > 0); \ - if (_tmp != NULL) \ - *_tmp = prev - 1; \ - } while (0) - -#endif /* ISC_REFCOUNT_HAVESTDATOMIC */ - -#else /* ISC_PLATFORM_HAVEXADD */ - -typedef struct isc_refcount { - int refs; - isc_mutex_t lock; -} isc_refcount_t; - -/*% Destroys a reference counter. */ -#define isc_refcount_destroy(rp) \ - do { \ - isc_result_t _result; \ - ISC_REQUIRE((rp)->refs == 0); \ - _result = isc_mutex_destroy(&(rp)->lock); \ - ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \ - } while (0) - -#define isc_refcount_current(rp) ((unsigned int)((rp)->refs)) - -/*% - * Increments the reference count, returning the new value in - * 'tp' if it's not NULL. - */ -#define isc_refcount_increment0(rp, tp) \ - do { \ - isc_result_t _result; \ - unsigned int *_tmp = (unsigned int *)(tp); \ - _result = isc_mutex_lock(&(rp)->lock); \ - ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \ - ++((rp)->refs); \ - if (_tmp != NULL) \ - *_tmp = ((rp)->refs); \ - _result = isc_mutex_unlock(&(rp)->lock); \ - ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \ - } while (0) - -#define isc_refcount_increment(rp, tp) \ - do { \ - isc_result_t _result; \ - unsigned int *_tmp = (unsigned int *)(tp); \ - _result = isc_mutex_lock(&(rp)->lock); \ - ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \ - ISC_REQUIRE((rp)->refs > 0); \ - ++((rp)->refs); \ - if (_tmp != NULL) \ - *_tmp = ((rp)->refs); \ - _result = isc_mutex_unlock(&(rp)->lock); \ - ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \ - } while (0) - -/*% - * Decrements the reference count, returning the new value in 'tp' - * if it's not NULL. - */ -#define isc_refcount_decrement(rp, tp) \ - do { \ - isc_result_t _result; \ - unsigned int *_tmp = (unsigned int *)(tp); \ - _result = isc_mutex_lock(&(rp)->lock); \ - ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \ - ISC_REQUIRE((rp)->refs > 0); \ - --((rp)->refs); \ - if (_tmp != NULL) \ - *_tmp = ((rp)->refs); \ - _result = isc_mutex_unlock(&(rp)->lock); \ - ISC_ERROR_RUNTIMECHECK(_result == ISC_R_SUCCESS); \ - } while (0) - -#endif /* (defined(ISC_PLATFORM_HAVESTDATOMIC) && defined(ATOMIC_INT_LOCK_FREE)) || defined(ISC_PLATFORM_HAVEXADD) */ -#else /* ISC_PLATFORM_USETHREADS */ - -typedef struct isc_refcount { - int refs; -} isc_refcount_t; - -#define isc_refcount_destroy(rp) ISC_REQUIRE((rp)->refs == 0) -#define isc_refcount_current(rp) ((unsigned int)((rp)->refs)) - -#define isc_refcount_increment0(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - int _n = ++(rp)->refs; \ - if (_tmp != NULL) \ - *_tmp = _n; \ - } while (0) - -#define isc_refcount_increment(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - int _n; \ - ISC_REQUIRE((rp)->refs > 0); \ - _n = ++(rp)->refs; \ - if (_tmp != NULL) \ - *_tmp = _n; \ - } while (0) - -#define isc_refcount_decrement(rp, tp) \ - do { \ - unsigned int *_tmp = (unsigned int *)(tp); \ - int _n; \ - ISC_REQUIRE((rp)->refs > 0); \ - _n = --(rp)->refs; \ - if (_tmp != NULL) \ - *_tmp = _n; \ - } while (0) +#define isc_refcount_increment0(target) \ + isc_refcount_increment(target) -#endif /* ISC_PLATFORM_USETHREADS */ +/** \def isc_refcount_increment(ref) + * \brief increases reference counter by 1. + * \param[in] ref pointer to reference counter. + * \returns previous value of reference counter. + */ +#define isc_refcount_increment(target) \ + atomic_fetch_add_explicit(target, 1, memory_order_relaxed) -isc_result_t -isc_refcount_init(isc_refcount_t *ref, unsigned int n); +/** \def isc_refcount_decrement(ref) + * \brief decreases reference counter by 1. + * \param[in] ref pointer to reference counter. + * \returns previous value of reference counter. + */ +#define isc_refcount_decrement(target) \ + atomic_fetch_sub_explicit(target, 1, memory_order_release) ISC_LANG_ENDDECLS - -#endif /* ISC_REFCOUNT_H */