File: [local] / sys / dev / raidframe / rf_freelist.h (download)
Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:09:48 2008 UTC (16 years, 4 months ago) by nbrk
Branch: OPENBSD_4_2_BASE, MAIN
CVS Tags: jornada-partial-support-wip, HEAD Changes since 1.1: +0 -0 lines
Import of OpenBSD 4.2 release kernel tree with initial code to support
Jornada 720/728, StrongARM 1110-based handheld PC.
At this point kernel roots on NFS and boots into vfs_mountroot() and traps.
What is supported:
- glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode
(needs some palette tweaks for non black/white/blue colors, i think)
- saic, SA11x0 interrupt controller (needs cleanup)
- sacom, SA11x0 UART (supported only as boot console for now)
- SA11x0 GPIO controller fully supported (but can't handle multiple interrupt
handlers on one gpio pin)
- sassp, SSP port on SA11x0 that attaches spibus
- Jornada microcontroller (jmcu) to control kbd, battery, etc throught
the SPI bus (wskbd attaches on jmcu, but not tested)
- tod functions seem work
- initial code for SA-1111 (chip companion) : this is TODO
Next important steps, i think:
- gpio and intc on sa1111
- pcmcia support for sa11x0 (and sa1111 help logic)
- REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs)
- root on wd0! (using already supported PCMCIA-ATA)
|
/* $OpenBSD: rf_freelist.h,v 1.3 2002/12/16 07:01:04 tdeval Exp $ */
/* $NetBSD: rf_freelist.h,v 1.3 1999/02/05 00:06:11 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 "rf_types.h"
#include "rf_debugMem.h"
#include "rf_general.h"
#include "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_) \
do { \
bzero((char *)&((_fl_)->stats), sizeof(RF_FreeListStats_t)); \
(_fl_)->stats.file = __FILE__; \
(_fl_)->stats.line = __LINE__; \
} while (0)
#define RF_FREELIST_STAT_ALLOC(_fl_) \
do { \
(_fl_)->stats.allocations++; \
(_fl_)->stats.outstanding++; \
if ((_fl_)->stats.outstanding > (_fl_)->stats.max_outstanding) \
(_fl_)->stats.max_outstanding = \
(_fl_)->stats.outstanding; \
} while (0)
#define RF_FREELIST_STAT_FREE_UPDATE(_fl_) \
do { \
if ((_fl_)->free_cnt > (_fl_)->stats.max_free) \
(_fl_)->stats.max_free = (_fl_)->free_cnt; \
} while (0)
#define RF_FREELIST_STAT_FREE(_fl_) \
do { \
(_fl_)->stats.frees++; \
(_fl_)->stats.outstanding--; \
RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
} while (0)
#define RF_FREELIST_STAT_GROW(_fl_) \
do { \
(_fl_)->stats.grows++; \
RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
} while (0)
#define RF_FREELIST_STAT_REPORT(_fl_) \
do { \
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); \
} while (0)
#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_) \
do { \
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); \
if (rc) { \
RF_Free(_fl_, sizeof(RF_FreeList_t)); \
_fl_ = NULL; \
} \
RF_FREELIST_STAT_INIT(_fl_); \
} while (0)
/*
* 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_) \
do { \
void *_p; \
int _i; \
RF_LOCK_MUTEX((_fl_)->lock); \
for (_i = 0; _i < (_cnt_); _i++) { \
RF_Calloc(_p, 1, (_fl_)->obj_size, (void *)); \
if (_p) { \
(_cast_(_p))->_nextp_ = (_fl_)->objlist; \
(_fl_)->objlist = _p; \
(_fl_)->free_cnt++; \
} \
else { \
break; \
} \
} \
RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
RF_UNLOCK_MUTEX((_fl_)->lock); \
} while (0)
#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_) \
do { \
void *_p; \
int _i; \
RF_LOCK_MUTEX((_fl_)->lock); \
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) { \
(_cast_(_p))->_nextp_ = (_fl_)->objlist; \
(_fl_)->objlist = _p; \
(_fl_)->free_cnt++; \
} \
else { \
break; \
} \
} \
RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
RF_UNLOCK_MUTEX((_fl_)->lock); \
} while (0)
/*
* 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_) \
do { \
void *_p; \
int _i; \
RF_LOCK_MUTEX((_fl_)->lock); \
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) { \
(_cast_(_p))->_nextp_ = (_fl_)->objlist; \
(_fl_)->objlist = _p; \
(_fl_)->free_cnt++; \
} \
else { \
break; \
} \
} \
RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
RF_UNLOCK_MUTEX((_fl_)->lock); \
} while (0)
/*
* 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_) \
do { \
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_); \
RF_UNLOCK_MUTEX((_fl_)->lock); \
} while (0)
/*
* 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_) \
do { \
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_, _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; \
} \
(_cast_(_p))->_nextp_ = \
(_fl_)->objlist; \
(_fl_)->objlist = _p; \
} \
else { \
break; \
} \
} \
} \
} \
RF_FREELIST_STAT_GROW(_fl_); \
} \
RF_FREELIST_STAT_ALLOC(_fl_); \
RF_UNLOCK_MUTEX((_fl_)->lock); \
} while (0)
/*
* 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_) \
do { \
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_); \
} while (0)
/*
* 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_) \
do { \
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_) { \
for (_i = 1; _i < (_fl_)->obj_inc; _i++) { \
RF_Calloc(_p, 1, (_fl_)->obj_size, \
(void *)); \
if (_p) { \
(_cast_(_p))->_nextp_ = \
(_fl_)->objlist; \
(_fl_)->objlist = _p; \
} \
else { \
break; \
} \
} \
} \
RF_FREELIST_STAT_GROW(_fl_); \
} \
RF_FREELIST_STAT_ALLOC(_fl_); \
RF_UNLOCK_MUTEX((_fl_)->lock); \
} while (0)
/*
* 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_) \
do { \
void *_p, *_l, *_f; \
int _i, _n; \
_l = _f = NULL; \
_n = 0; \
RF_LOCK_MUTEX((_fl_)->lock); \
RF_ASSERT(sizeof(*(_obj_)) == ((_fl_)->obj_size)); \
for (_n = 0; _n < _num_; _n++) { \
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_) { \
for (_i = 1; _i < (_fl_)->obj_inc; \
_i++) { \
RF_Calloc(_p, 1, \
(_fl_)->obj_size, \
(void *)); \
if (_p) { \
(_cast_(_p))->_nextp_ = \
(_fl_)->objlist; \
(_fl_)->objlist = _p; \
} \
else { \
break; \
} \
} \
} \
RF_FREELIST_STAT_GROW(_fl_); \
} \
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); \
} while (0)
/*
* fl = FreeList.
* obj = Object to free.
* nextp = Name of "next" pointer in obj.
*/
#define RF_FREELIST_FREE(_fl_,_obj_,_nextp_) \
do { \
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); \
} while (0)
/*
* 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_) \
do { \
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); \
} while (0)
/*
* 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_) \
do { \
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); \
} while (0)
/*
* 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_) \
do { \
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); \
} while (0)
/*
* 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_) \
do { \
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_); \
} while (0)
/*
* fl = FreeList.
* nextp = Name of "next" pointer in obj.
* cast = Cast to object type.
*/
#define RF_FREELIST_DESTROY(_fl_,_nextp_,_cast_) \
do { \
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)); \
} while (0)
/*
* 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_) \
do { \
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)); \
} while (0)
/*
* 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_) \
do { \
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)); \
} while (0)
#endif /* !_RF__RF_FREELIST_H_ */