summaryrefslogtreecommitdiffstats
path: root/sys/dev/raidframe/rf_freelist.h
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2002-10-20 08:17:39 +0000
committerscottl <scottl@FreeBSD.org>2002-10-20 08:17:39 +0000
commit710948de69ddeae56bda663219319f6d859aea1f (patch)
tree71c65823ba2e8591de708d5cb2e990a75135ee11 /sys/dev/raidframe/rf_freelist.h
parent63bd46464d6d4587c20c1ca62fb6a6e3be132db9 (diff)
downloadFreeBSD-src-710948de69ddeae56bda663219319f6d859aea1f.zip
FreeBSD-src-710948de69ddeae56bda663219319f6d859aea1f.tar.gz
After much delay and anticipation, welcome RAIDFrame into the FreeBSD
world. This should be considered highly experimental. Approved-by: re
Diffstat (limited to 'sys/dev/raidframe/rf_freelist.h')
-rw-r--r--sys/dev/raidframe/rf_freelist.h702
1 files changed, 702 insertions, 0 deletions
diff --git a/sys/dev/raidframe/rf_freelist.h b/sys/dev/raidframe/rf_freelist.h
new file mode 100644
index 0000000..13a5e83
--- /dev/null
+++ b/sys/dev/raidframe/rf_freelist.h
@@ -0,0 +1,702 @@
+/* $FreeBSD$ */
+/* $NetBSD: rf_freelist.h,v 1.6 2002/08/08 02:53:01 oster Exp $ */
+/*
+ * rf_freelist.h
+ */
+/*
+ * Copyright (c) 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Jim Zelenka
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+/*
+ * rf_freelist.h -- code to manage counted freelists
+ *
+ * Keep an arena of fixed-size objects. When a new object is needed,
+ * allocate it as necessary. When an object is freed, either put it
+ * in the arena, or really free it, depending on the maximum arena
+ * size.
+ */
+
+#ifndef _RF__RF_FREELIST_H_
+#define _RF__RF_FREELIST_H_
+
+#include <dev/raidframe/rf_types.h>
+#include <dev/raidframe/rf_debugMem.h>
+#include <dev/raidframe/rf_general.h>
+#include <dev/raidframe/rf_threadstuff.h>
+
+#define RF_FREELIST_STATS 0
+
+#if RF_FREELIST_STATS > 0
+typedef struct RF_FreeListStats_s {
+ char *file;
+ int line;
+ int allocations;
+ int frees;
+ int max_free;
+ int grows;
+ int outstanding;
+ int max_outstanding;
+} RF_FreeListStats_t;
+#define RF_FREELIST_STAT_INIT(_fl_) { \
+ bzero((char *)&((_fl_)->stats), sizeof(RF_FreeListStats_t)); \
+ (_fl_)->stats.file = __FILE__; \
+ (_fl_)->stats.line = __LINE__; \
+}
+
+#define RF_FREELIST_STAT_ALLOC(_fl_) { \
+ (_fl_)->stats.allocations++; \
+ (_fl_)->stats.outstanding++; \
+ if ((_fl_)->stats.outstanding > (_fl_)->stats.max_outstanding) \
+ (_fl_)->stats.max_outstanding = (_fl_)->stats.outstanding; \
+}
+
+#define RF_FREELIST_STAT_FREE_UPDATE(_fl_) { \
+ if ((_fl_)->free_cnt > (_fl_)->stats.max_free) \
+ (_fl_)->stats.max_free = (_fl_)->free_cnt; \
+}
+
+#define RF_FREELIST_STAT_FREE(_fl_) { \
+ (_fl_)->stats.frees++; \
+ (_fl_)->stats.outstanding--; \
+ RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
+}
+
+#define RF_FREELIST_STAT_GROW(_fl_) { \
+ (_fl_)->stats.grows++; \
+ RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
+}
+
+#define RF_FREELIST_STAT_REPORT(_fl_) { \
+ printf("Freelist at %s %d (%s)\n", (_fl_)->stats.file, (_fl_)->stats.line, RF_STRING(_fl_)); \
+ printf(" %d allocations, %d frees\n", (_fl_)->stats.allocations, (_fl_)->stats.frees); \
+ printf(" %d grows\n", (_fl_)->stats.grows); \
+ printf(" %d outstanding\n", (_fl_)->stats.outstanding); \
+ printf(" %d free (max)\n", (_fl_)->stats.max_free); \
+ printf(" %d outstanding (max)\n", (_fl_)->stats.max_outstanding); \
+}
+
+#else /* RF_FREELIST_STATS > 0 */
+
+#define RF_FREELIST_STAT_INIT(_fl_)
+#define RF_FREELIST_STAT_ALLOC(_fl_)
+#define RF_FREELIST_STAT_FREE_UPDATE(_fl_)
+#define RF_FREELIST_STAT_FREE(_fl_)
+#define RF_FREELIST_STAT_GROW(_fl_)
+#define RF_FREELIST_STAT_REPORT(_fl_)
+
+#endif /* RF_FREELIST_STATS > 0 */
+
+struct RF_FreeList_s {
+ void *objlist; /* list of free obj */
+ int free_cnt; /* how many free obj */
+ int max_free_cnt; /* max free arena size */
+ int obj_inc; /* how many to allocate at a time */
+ int obj_size; /* size of objects */
+ RF_DECLARE_MUTEX(lock)
+#if RF_FREELIST_STATS > 0
+ RF_FreeListStats_t stats; /* statistics */
+#endif /* RF_FREELIST_STATS > 0 */
+};
+/*
+ * fl = freelist
+ * maxcnt = max number of items in arena
+ * inc = how many to allocate at a time
+ * size = size of object
+ */
+#define RF_FREELIST_CREATE(_fl_,_maxcnt_,_inc_,_size_) { \
+ int rc; \
+ RF_ASSERT((_inc_) > 0); \
+ RF_Malloc(_fl_, sizeof(RF_FreeList_t), (RF_FreeList_t *)); \
+ (_fl_)->objlist = NULL; \
+ (_fl_)->free_cnt = 0; \
+ (_fl_)->max_free_cnt = _maxcnt_; \
+ (_fl_)->obj_inc = _inc_; \
+ (_fl_)->obj_size = _size_; \
+ rc = rf_mutex_init(&(_fl_)->lock, "RF_FREELIST"); \
+ if (rc) { \
+ RF_Free(_fl_, sizeof(RF_FreeList_t)); \
+ _fl_ = NULL; \
+ } \
+ RF_FREELIST_STAT_INIT(_fl_); \
+}
+
+/*
+ * fl = freelist
+ * cnt = number to prime with
+ * nextp = name of "next" pointer in obj
+ * cast = object cast
+ */
+#define RF_FREELIST_PRIME(_fl_,_cnt_,_nextp_,_cast_) { \
+ void *_p; \
+ int _i; \
+ for(_i=0;_i<(_cnt_);_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_p) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ (_fl_)->free_cnt++; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+#define RF_FREELIST_MUTEX_OF(_fl_) ((_fl_)->lock)
+
+#define RF_FREELIST_DO_UNLOCK(_fl_) { \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+#define RF_FREELIST_DO_LOCK(_fl_) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * cnt = number to prime with
+ * nextp = name of "next" pointer in obj
+ * cast = object cast
+ * init = func to call to init obj
+ */
+#define RF_FREELIST_PRIME_INIT(_fl_,_cnt_,_nextp_,_cast_,_init_) { \
+ void *_p; \
+ int _i; \
+ for(_i=0;_i<(_cnt_);_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_init_ (_cast_ _p)) { \
+ RF_Free(_p,(_fl_)->obj_size); \
+ _p = NULL; \
+ } \
+ if (_p) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ (_fl_)->free_cnt++; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * cnt = number to prime with
+ * nextp = name of "next" pointer in obj
+ * cast = object cast
+ * init = func to call to init obj
+ * arg = arg to init obj func
+ */
+#define RF_FREELIST_PRIME_INIT_ARG(_fl_,_cnt_,_nextp_,_cast_,_init_,_arg_) { \
+ void *_p; \
+ int _i; \
+ for(_i=0;_i<(_cnt_);_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_init_ (_cast_ _p,_arg_)) { \
+ RF_Free(_p,(_fl_)->obj_size); \
+ _p = NULL; \
+ } \
+ if (_p) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ (_fl_)->free_cnt++; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to allocate
+ * nextp = name of "next" pointer in obj
+ * cast = cast of obj assignment
+ * init = init obj func
+ */
+#define RF_FREELIST_GET_INIT(_fl_,_obj_,_nextp_,_cast_,_init_) { \
+ void *_p; \
+ int _i; \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_ASSERT(sizeof(*(_obj_))==((_fl_)->obj_size)); \
+ if (_fl_->objlist) { \
+ _obj_ = _cast_((_fl_)->objlist); \
+ (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
+ (_fl_)->free_cnt--; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ /* \
+ * Allocate one at a time so we can free \
+ * one at a time without cleverness when arena \
+ * is full. \
+ */ \
+ RF_Calloc(_obj_,1,(_fl_)->obj_size,_cast_); \
+ if (_obj_) { \
+ if (_init_ (_obj_)) { \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ _obj_ = NULL; \
+ } \
+ else { \
+ for(_i=1;_i<(_fl_)->obj_inc;_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_p) { \
+ if (_init_ (_p)) { \
+ RF_Free(_p,(_fl_)->obj_size); \
+ _p = NULL; \
+ break; \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ } \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_GROW(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_ALLOC(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to allocate
+ * nextp = name of "next" pointer in obj
+ * cast = cast of obj assignment
+ * init = init obj func
+ * arg = arg to init obj func
+ */
+#define RF_FREELIST_GET_INIT_ARG(_fl_,_obj_,_nextp_,_cast_,_init_,_arg_) { \
+ void *_p; \
+ int _i; \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_ASSERT(sizeof(*(_obj_))==((_fl_)->obj_size)); \
+ if (_fl_->objlist) { \
+ _obj_ = _cast_((_fl_)->objlist); \
+ (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
+ (_fl_)->free_cnt--; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ /* \
+ * Allocate one at a time so we can free \
+ * one at a time without cleverness when arena \
+ * is full. \
+ */ \
+ RF_Calloc(_obj_,1,(_fl_)->obj_size,_cast_); \
+ if (_obj_) { \
+ if (_init_ (_obj_,_arg_)) { \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ _obj_ = NULL; \
+ } \
+ else { \
+ for(_i=1;_i<(_fl_)->obj_inc;_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_p) { \
+ if (_init_ (_p,_arg_)) { \
+ RF_Free(_p,(_fl_)->obj_size); \
+ _p = NULL; \
+ break; \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ } \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_GROW(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_ALLOC(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to allocate
+ * nextp = name of "next" pointer in obj
+ * cast = cast of obj assignment
+ * init = init obj func
+ */
+#define RF_FREELIST_GET_INIT_NOUNLOCK(_fl_,_obj_,_nextp_,_cast_,_init_) { \
+ void *_p; \
+ int _i; \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_ASSERT(sizeof(*(_obj_))==((_fl_)->obj_size)); \
+ if (_fl_->objlist) { \
+ _obj_ = _cast_((_fl_)->objlist); \
+ (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
+ (_fl_)->free_cnt--; \
+ } \
+ else { \
+ /* \
+ * Allocate one at a time so we can free \
+ * one at a time without cleverness when arena \
+ * is full. \
+ */ \
+ RF_Calloc(_obj_,1,(_fl_)->obj_size,_cast_); \
+ if (_obj_) { \
+ if (_init_ (_obj_)) { \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ _obj_ = NULL; \
+ } \
+ else { \
+ for(_i=1;_i<(_fl_)->obj_inc;_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_p) { \
+ if (_init_ (_p)) { \
+ RF_Free(_p,(_fl_)->obj_size); \
+ _p = NULL; \
+ break; \
+ } \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ } \
+ } \
+ RF_FREELIST_STAT_GROW(_fl_); \
+ } \
+ RF_FREELIST_STAT_ALLOC(_fl_); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to allocate
+ * nextp = name of "next" pointer in obj
+ * cast = cast of obj assignment
+ */
+#define RF_FREELIST_GET(_fl_,_obj_,_nextp_,_cast_) { \
+ void *_p; \
+ int _i; \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_ASSERT(sizeof(*(_obj_))==((_fl_)->obj_size)); \
+ if (_fl_->objlist) { \
+ _obj_ = _cast_((_fl_)->objlist); \
+ (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
+ (_fl_)->free_cnt--; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ /* \
+ * Allocate one at a time so we can free \
+ * one at a time without cleverness when arena \
+ * is full. \
+ */ \
+ RF_Calloc(_obj_,1,(_fl_)->obj_size,_cast_); \
+ if (_obj_) { \
+ for(_i=1;_i<(_fl_)->obj_inc;_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_p) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_GROW(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_ALLOC(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to allocate
+ * nextp = name of "next" pointer in obj
+ * cast = cast of obj assignment
+ * num = num objs to return
+ */
+#define RF_FREELIST_GET_N(_fl_,_obj_,_nextp_,_cast_,_num_) { \
+ void *_p, *_l, *_f; \
+ int _i, _n; \
+ _l = _f = NULL; \
+ _n = 0; \
+ RF_ASSERT(sizeof(*(_obj_))==((_fl_)->obj_size)); \
+ for(_n=0;_n<_num_;_n++) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ if (_fl_->objlist) { \
+ _obj_ = _cast_((_fl_)->objlist); \
+ (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
+ (_fl_)->free_cnt--; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ /* \
+ * Allocate one at a time so we can free \
+ * one at a time without cleverness when arena \
+ * is full. \
+ */ \
+ RF_Calloc(_obj_,1,(_fl_)->obj_size,_cast_); \
+ if (_obj_) { \
+ for(_i=1;_i<(_fl_)->obj_inc;_i++) { \
+ RF_Calloc(_p,1,(_fl_)->obj_size,(void *)); \
+ if (_p) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _p; \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ else { \
+ break; \
+ } \
+ } \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ RF_FREELIST_STAT_GROW(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ if (_f == NULL) \
+ _f = _obj_; \
+ if (_obj_) { \
+ (_cast_(_obj_))->_nextp_ = _l; \
+ _l = _obj_; \
+ RF_FREELIST_STAT_ALLOC(_fl_); \
+ } \
+ else { \
+ (_cast_(_f))->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = _l; \
+ _n = _num_; \
+ } \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+ } \
+}
+
+/*
+ * fl = freelist
+ * obj = object to free
+ * nextp = name of "next" pointer in obj
+ */
+#define RF_FREELIST_FREE(_fl_,_obj_,_nextp_) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ } \
+ else { \
+ RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
+ (_obj_)->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = (void *)(_obj_); \
+ (_fl_)->free_cnt++; \
+ } \
+ RF_FREELIST_STAT_FREE(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to free
+ * nextp = name of "next" pointer in obj
+ * num = num to free (debugging)
+ */
+#define RF_FREELIST_FREE_N(_fl_,_obj_,_nextp_,_cast_,_num_) { \
+ void *_no; \
+ int _n; \
+ _n = 0; \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ while(_obj_) { \
+ _no = (_cast_(_obj_))->_nextp_; \
+ if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ } \
+ else { \
+ RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
+ (_obj_)->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = (void *)(_obj_); \
+ (_fl_)->free_cnt++; \
+ } \
+ _n++; \
+ _obj_ = _no; \
+ RF_FREELIST_STAT_FREE(_fl_); \
+ } \
+ RF_ASSERT(_n==(_num_)); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to free
+ * nextp = name of "next" pointer in obj
+ * clean = undo for init
+ */
+#define RF_FREELIST_FREE_CLEAN(_fl_,_obj_,_nextp_,_clean_) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
+ _clean_ (_obj_); \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ } \
+ else { \
+ RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
+ (_obj_)->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = (void *)(_obj_); \
+ (_fl_)->free_cnt++; \
+ } \
+ RF_FREELIST_STAT_FREE(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to free
+ * nextp = name of "next" pointer in obj
+ * clean = undo for init
+ * arg = arg for undo func
+ */
+#define RF_FREELIST_FREE_CLEAN_ARG(_fl_,_obj_,_nextp_,_clean_,_arg_) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
+ _clean_ (_obj_,_arg_); \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ } \
+ else { \
+ RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
+ (_obj_)->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = (void *)(_obj_); \
+ (_fl_)->free_cnt++; \
+ } \
+ RF_FREELIST_STAT_FREE(_fl_); \
+ RF_UNLOCK_MUTEX((_fl_)->lock); \
+}
+
+/*
+ * fl = freelist
+ * obj = object to free
+ * nextp = name of "next" pointer in obj
+ * clean = undo for init
+ */
+#define RF_FREELIST_FREE_CLEAN_NOUNLOCK(_fl_,_obj_,_nextp_,_clean_) { \
+ RF_LOCK_MUTEX((_fl_)->lock); \
+ if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
+ _clean_ (_obj_); \
+ RF_Free(_obj_,(_fl_)->obj_size); \
+ } \
+ else { \
+ RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
+ (_obj_)->_nextp_ = (_fl_)->objlist; \
+ (_fl_)->objlist = (void *)(_obj_); \
+ (_fl_)->free_cnt++; \
+ } \
+ RF_FREELIST_STAT_FREE(_fl_); \
+}
+
+/*
+ * fl = freelist
+ * nextp = name of "next" pointer in obj
+ * cast = cast to object type
+ */
+#define RF_FREELIST_DESTROY(_fl_,_nextp_,_cast_) { \
+ void *_cur, *_next; \
+ RF_FREELIST_STAT_REPORT(_fl_); \
+ rf_mutex_destroy(&((_fl_)->lock)); \
+ for(_cur=(_fl_)->objlist;_cur;_cur=_next) { \
+ _next = (_cast_ _cur)->_nextp_; \
+ RF_Free(_cur,(_fl_)->obj_size); \
+ } \
+ RF_Free(_fl_,sizeof(RF_FreeList_t)); \
+}
+
+/*
+ * fl = freelist
+ * nextp = name of "next" pointer in obj
+ * cast = cast to object type
+ * clean = func to undo obj init
+ */
+#define RF_FREELIST_DESTROY_CLEAN(_fl_,_nextp_,_cast_,_clean_) { \
+ void *_cur, *_next; \
+ RF_FREELIST_STAT_REPORT(_fl_); \
+ rf_mutex_destroy(&((_fl_)->lock)); \
+ for(_cur=(_fl_)->objlist;_cur;_cur=_next) { \
+ _next = (_cast_ _cur)->_nextp_; \
+ _clean_ (_cur); \
+ RF_Free(_cur,(_fl_)->obj_size); \
+ } \
+ RF_Free(_fl_,sizeof(RF_FreeList_t)); \
+}
+
+/*
+ * fl = freelist
+ * nextp = name of "next" pointer in obj
+ * cast = cast to object type
+ * clean = func to undo obj init
+ * arg = arg for undo func
+ */
+#define RF_FREELIST_DESTROY_CLEAN_ARG(_fl_,_nextp_,_cast_,_clean_,_arg_) { \
+ void *_cur, *_next; \
+ RF_FREELIST_STAT_REPORT(_fl_); \
+ rf_mutex_destroy(&((_fl_)->lock)); \
+ for(_cur=(_fl_)->objlist;_cur;_cur=_next) { \
+ _next = (_cast_ _cur)->_nextp_; \
+ _clean_ (_cur,_arg_); \
+ RF_Free(_cur,(_fl_)->obj_size); \
+ } \
+ RF_Free(_fl_,sizeof(RF_FreeList_t)); \
+}
+
+#endif /* !_RF__RF_FREELIST_H_ */
OpenPOWER on IntegriCloud