00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef ISC_REFCOUNT_H
00021 #define ISC_REFCOUNT_H 1
00022
00023 #include <isc/atomic.h>
00024 #include <isc/lang.h>
00025 #include <isc/mutex.h>
00026 #include <isc/platform.h>
00027 #include <isc/types.h>
00028 #include <isc/util.h>
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 ISC_LANG_BEGINDECLS
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 #ifdef ISC_PLATFORM_USETHREADS
00098 #ifdef ISC_PLATFORM_HAVEXADD
00099
00100 #define ISC_REFCOUNT_HAVEATOMIC 1
00101
00102 typedef struct isc_refcount {
00103 isc_int32_t refs;
00104 } isc_refcount_t;
00105
00106 #define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0)
00107 #define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
00108
00109 #define isc_refcount_increment0(rp, tp) \
00110 do { \
00111 unsigned int *_tmp = (unsigned int *)(tp); \
00112 isc_int32_t prev; \
00113 prev = isc_atomic_xadd(&(rp)->refs, 1); \
00114 if (_tmp != NULL) \
00115 *_tmp = prev + 1; \
00116 } while (0)
00117
00118 #define isc_refcount_increment(rp, tp) \
00119 do { \
00120 unsigned int *_tmp = (unsigned int *)(tp); \
00121 isc_int32_t prev; \
00122 prev = isc_atomic_xadd(&(rp)->refs, 1); \
00123 REQUIRE(prev > 0); \
00124 if (_tmp != NULL) \
00125 *_tmp = prev + 1; \
00126 } while (0)
00127
00128 #define isc_refcount_decrement(rp, tp) \
00129 do { \
00130 unsigned int *_tmp = (unsigned int *)(tp); \
00131 isc_int32_t prev; \
00132 prev = isc_atomic_xadd(&(rp)->refs, -1); \
00133 REQUIRE(prev > 0); \
00134 if (_tmp != NULL) \
00135 *_tmp = prev - 1; \
00136 } while (0)
00137
00138 #else
00139
00140 typedef struct isc_refcount {
00141 int refs;
00142 isc_mutex_t lock;
00143 } isc_refcount_t;
00144
00145
00146 #define isc_refcount_destroy(rp) \
00147 do { \
00148 REQUIRE((rp)->refs == 0); \
00149 DESTROYLOCK(&(rp)->lock); \
00150 } while (0)
00151
00152 #define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
00153
00154
00155 #define isc_refcount_increment0(rp, tp) \
00156 do { \
00157 unsigned int *_tmp = (unsigned int *)(tp); \
00158 LOCK(&(rp)->lock); \
00159 ++((rp)->refs); \
00160 if (_tmp != NULL) \
00161 *_tmp = ((rp)->refs); \
00162 UNLOCK(&(rp)->lock); \
00163 } while (0)
00164
00165 #define isc_refcount_increment(rp, tp) \
00166 do { \
00167 unsigned int *_tmp = (unsigned int *)(tp); \
00168 LOCK(&(rp)->lock); \
00169 REQUIRE((rp)->refs > 0); \
00170 ++((rp)->refs); \
00171 if (_tmp != NULL) \
00172 *_tmp = ((rp)->refs); \
00173 UNLOCK(&(rp)->lock); \
00174 } while (0)
00175
00176
00177 #define isc_refcount_decrement(rp, tp) \
00178 do { \
00179 unsigned int *_tmp = (unsigned int *)(tp); \
00180 LOCK(&(rp)->lock); \
00181 REQUIRE((rp)->refs > 0); \
00182 --((rp)->refs); \
00183 if (_tmp != NULL) \
00184 *_tmp = ((rp)->refs); \
00185 UNLOCK(&(rp)->lock); \
00186 } while (0)
00187
00188 #endif
00189 #else
00190
00191 typedef struct isc_refcount {
00192 int refs;
00193 } isc_refcount_t;
00194
00195 #define isc_refcount_destroy(rp) REQUIRE((rp)->refs == 0)
00196 #define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
00197
00198 #define isc_refcount_increment0(rp, tp) \
00199 do { \
00200 unsigned int *_tmp = (unsigned int *)(tp); \
00201 int _n = ++(rp)->refs; \
00202 if (_tmp != NULL) \
00203 *_tmp = _n; \
00204 } while (0)
00205
00206 #define isc_refcount_increment(rp, tp) \
00207 do { \
00208 unsigned int *_tmp = (unsigned int *)(tp); \
00209 int _n; \
00210 REQUIRE((rp)->refs > 0); \
00211 _n = ++(rp)->refs; \
00212 if (_tmp != NULL) \
00213 *_tmp = _n; \
00214 } while (0)
00215
00216 #define isc_refcount_decrement(rp, tp) \
00217 do { \
00218 unsigned int *_tmp = (unsigned int *)(tp); \
00219 int _n; \
00220 REQUIRE((rp)->refs > 0); \
00221 _n = --(rp)->refs; \
00222 if (_tmp != NULL) \
00223 *_tmp = _n; \
00224 } while (0)
00225
00226 #endif
00227
00228 isc_result_t
00229 isc_refcount_init(isc_refcount_t *ref, unsigned int n);
00230
00231 ISC_LANG_ENDDECLS
00232
00233 #endif