Annotation of sys/dev/raidframe/rf_freelist.h, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: rf_freelist.h,v 1.3 2002/12/16 07:01:04 tdeval Exp $ */
! 2: /* $NetBSD: rf_freelist.h,v 1.3 1999/02/05 00:06:11 oster Exp $ */
! 3:
! 4: /*
! 5: * rf_freelist.h
! 6: */
! 7: /*
! 8: * Copyright (c) 1995 Carnegie-Mellon University.
! 9: * All rights reserved.
! 10: *
! 11: * Author: Jim Zelenka
! 12: *
! 13: * Permission to use, copy, modify and distribute this software and
! 14: * its documentation is hereby granted, provided that both the copyright
! 15: * notice and this permission notice appear in all copies of the
! 16: * software, derivative works or modified versions, and any portions
! 17: * thereof, and that both notices appear in supporting documentation.
! 18: *
! 19: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
! 20: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
! 21: * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
! 22: *
! 23: * Carnegie Mellon requests users of this software to return to
! 24: *
! 25: * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
! 26: * School of Computer Science
! 27: * Carnegie Mellon University
! 28: * Pittsburgh PA 15213-3890
! 29: *
! 30: * any improvements or extensions that they make and grant Carnegie the
! 31: * rights to redistribute these changes.
! 32: */
! 33:
! 34: /*
! 35: * rf_freelist.h -- Code to manage counted freelists.
! 36: *
! 37: * Keep an arena of fixed-size objects. When a new object is needed,
! 38: * allocate it as necessary. When an object is freed, either put it
! 39: * in the arena, or really free it, depending on the maximum arena
! 40: * size.
! 41: */
! 42:
! 43: #ifndef _RF__RF_FREELIST_H_
! 44: #define _RF__RF_FREELIST_H_
! 45:
! 46: #include "rf_types.h"
! 47: #include "rf_debugMem.h"
! 48: #include "rf_general.h"
! 49: #include "rf_threadstuff.h"
! 50:
! 51: #define RF_FREELIST_STATS 0
! 52:
! 53: #if RF_FREELIST_STATS > 0
! 54: typedef struct RF_FreeListStats_s {
! 55: char *file;
! 56: int line;
! 57: int allocations;
! 58: int frees;
! 59: int max_free;
! 60: int grows;
! 61: int outstanding;
! 62: int max_outstanding;
! 63: } RF_FreeListStats_t;
! 64:
! 65: #define RF_FREELIST_STAT_INIT(_fl_) \
! 66: do { \
! 67: bzero((char *)&((_fl_)->stats), sizeof(RF_FreeListStats_t)); \
! 68: (_fl_)->stats.file = __FILE__; \
! 69: (_fl_)->stats.line = __LINE__; \
! 70: } while (0)
! 71:
! 72: #define RF_FREELIST_STAT_ALLOC(_fl_) \
! 73: do { \
! 74: (_fl_)->stats.allocations++; \
! 75: (_fl_)->stats.outstanding++; \
! 76: if ((_fl_)->stats.outstanding > (_fl_)->stats.max_outstanding) \
! 77: (_fl_)->stats.max_outstanding = \
! 78: (_fl_)->stats.outstanding; \
! 79: } while (0)
! 80:
! 81: #define RF_FREELIST_STAT_FREE_UPDATE(_fl_) \
! 82: do { \
! 83: if ((_fl_)->free_cnt > (_fl_)->stats.max_free) \
! 84: (_fl_)->stats.max_free = (_fl_)->free_cnt; \
! 85: } while (0)
! 86:
! 87: #define RF_FREELIST_STAT_FREE(_fl_) \
! 88: do { \
! 89: (_fl_)->stats.frees++; \
! 90: (_fl_)->stats.outstanding--; \
! 91: RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
! 92: } while (0)
! 93:
! 94: #define RF_FREELIST_STAT_GROW(_fl_) \
! 95: do { \
! 96: (_fl_)->stats.grows++; \
! 97: RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
! 98: } while (0)
! 99:
! 100: #define RF_FREELIST_STAT_REPORT(_fl_) \
! 101: do { \
! 102: printf("Freelist at %s %d (%s)\n", (_fl_)->stats.file, \
! 103: (_fl_)->stats.line, RF_STRING(_fl_)); \
! 104: printf(" %d allocations, %d frees\n", \
! 105: (_fl_)->stats.allocations, (_fl_)->stats.frees); \
! 106: printf(" %d grows\n", (_fl_)->stats.grows); \
! 107: printf(" %d outstanding\n", (_fl_)->stats.outstanding); \
! 108: printf(" %d free (max)\n", (_fl_)->stats.max_free); \
! 109: printf(" %d outstanding (max)\n", \
! 110: (_fl_)->stats.max_outstanding); \
! 111: } while (0)
! 112:
! 113: #else /* RF_FREELIST_STATS > 0 */
! 114:
! 115: #define RF_FREELIST_STAT_INIT(_fl_)
! 116: #define RF_FREELIST_STAT_ALLOC(_fl_)
! 117: #define RF_FREELIST_STAT_FREE_UPDATE(_fl_)
! 118: #define RF_FREELIST_STAT_FREE(_fl_)
! 119: #define RF_FREELIST_STAT_GROW(_fl_)
! 120: #define RF_FREELIST_STAT_REPORT(_fl_)
! 121:
! 122: #endif /* RF_FREELIST_STATS > 0 */
! 123:
! 124: struct RF_FreeList_s {
! 125: void *objlist; /* List of free obj. */
! 126: int free_cnt; /* How many free obj. */
! 127: int max_free_cnt; /* Max free arena size. */
! 128: int obj_inc; /* How many to allocate at a time. */
! 129: int obj_size; /* Size of objects. */
! 130: RF_DECLARE_MUTEX(lock);
! 131: #if RF_FREELIST_STATS > 0
! 132: RF_FreeListStats_t stats; /* Statistics. */
! 133: #endif /* RF_FREELIST_STATS > 0 */
! 134: };
! 135:
! 136: /*
! 137: * fl = FreeList.
! 138: * maxcnt = Max number of items in arena.
! 139: * inc = How many to allocate at a time.
! 140: * size = Size of object.
! 141: */
! 142: #define RF_FREELIST_CREATE(_fl_,_maxcnt_,_inc_,_size_) \
! 143: do { \
! 144: int rc; \
! 145: RF_ASSERT((_inc_) > 0); \
! 146: RF_Malloc(_fl_, sizeof(RF_FreeList_t), (RF_FreeList_t *)); \
! 147: (_fl_)->objlist = NULL; \
! 148: (_fl_)->free_cnt = 0; \
! 149: (_fl_)->max_free_cnt = _maxcnt_; \
! 150: (_fl_)->obj_inc = _inc_; \
! 151: (_fl_)->obj_size = _size_; \
! 152: rc = rf_mutex_init(&(_fl_)->lock); \
! 153: if (rc) { \
! 154: RF_Free(_fl_, sizeof(RF_FreeList_t)); \
! 155: _fl_ = NULL; \
! 156: } \
! 157: RF_FREELIST_STAT_INIT(_fl_); \
! 158: } while (0)
! 159:
! 160: /*
! 161: * fl = FreeList.
! 162: * cnt = Number to prime with.
! 163: * nextp = Name of "next" pointer in obj.
! 164: * cast = Object cast.
! 165: */
! 166: #define RF_FREELIST_PRIME(_fl_,_cnt_,_nextp_,_cast_) \
! 167: do { \
! 168: void *_p; \
! 169: int _i; \
! 170: RF_LOCK_MUTEX((_fl_)->lock); \
! 171: for (_i = 0; _i < (_cnt_); _i++) { \
! 172: RF_Calloc(_p, 1, (_fl_)->obj_size, (void *)); \
! 173: if (_p) { \
! 174: (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
! 175: (_fl_)->objlist = _p; \
! 176: (_fl_)->free_cnt++; \
! 177: } \
! 178: else { \
! 179: break; \
! 180: } \
! 181: } \
! 182: RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
! 183: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 184: } while (0)
! 185:
! 186: #define RF_FREELIST_MUTEX_OF(_fl_) ((_fl_)->lock)
! 187:
! 188: #define RF_FREELIST_DO_UNLOCK(_fl_) RF_UNLOCK_MUTEX((_fl_)->lock)
! 189:
! 190: #define RF_FREELIST_DO_LOCK(_fl_) RF_LOCK_MUTEX((_fl_)->lock)
! 191:
! 192: /*
! 193: * fl = FreeList.
! 194: * cnt = Number to prime with.
! 195: * nextp = Name of "next" pointer in obj.
! 196: * cast = Object cast.
! 197: * init = Func to call to init obj.
! 198: */
! 199: #define RF_FREELIST_PRIME_INIT(_fl_,_cnt_,_nextp_,_cast_,_init_) \
! 200: do { \
! 201: void *_p; \
! 202: int _i; \
! 203: RF_LOCK_MUTEX((_fl_)->lock); \
! 204: for (_i = 0; _i < (_cnt_); _i++) { \
! 205: RF_Calloc(_p, 1, (_fl_)->obj_size, (void *)); \
! 206: if (_init_(_cast_ _p)) { \
! 207: RF_Free(_p, (_fl_)->obj_size); \
! 208: _p = NULL; \
! 209: } \
! 210: if (_p) { \
! 211: (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
! 212: (_fl_)->objlist = _p; \
! 213: (_fl_)->free_cnt++; \
! 214: } \
! 215: else { \
! 216: break; \
! 217: } \
! 218: } \
! 219: RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
! 220: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 221: } while (0)
! 222:
! 223: /*
! 224: * fl = FreeList.
! 225: * cnt = Number to prime with.
! 226: * nextp = Name of "next" pointer in obj.
! 227: * cast = Object cast.
! 228: * init = Func to call to init obj.
! 229: * arg = Arg to init obj func.
! 230: */
! 231: #define RF_FREELIST_PRIME_INIT_ARG(_fl_,_cnt_,_nextp_,_cast_,_init_,_arg_) \
! 232: do { \
! 233: void *_p; \
! 234: int _i; \
! 235: RF_LOCK_MUTEX((_fl_)->lock); \
! 236: for (_i = 0; _i < (_cnt_); _i++) { \
! 237: RF_Calloc(_p, 1, (_fl_)->obj_size, (void *)); \
! 238: if (_init_(_cast_ _p, _arg_)) { \
! 239: RF_Free(_p, (_fl_)->obj_size); \
! 240: _p = NULL; \
! 241: } \
! 242: if (_p) { \
! 243: (_cast_(_p))->_nextp_ = (_fl_)->objlist; \
! 244: (_fl_)->objlist = _p; \
! 245: (_fl_)->free_cnt++; \
! 246: } \
! 247: else { \
! 248: break; \
! 249: } \
! 250: } \
! 251: RF_FREELIST_STAT_FREE_UPDATE(_fl_); \
! 252: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 253: } while (0)
! 254:
! 255: /*
! 256: * fl = FreeList.
! 257: * obj = Object to allocate.
! 258: * nextp = Name of "next" pointer in obj.
! 259: * cast = Cast of obj assignment.
! 260: * init = Init obj func.
! 261: */
! 262: #define RF_FREELIST_GET_INIT(_fl_,_obj_,_nextp_,_cast_,_init_) \
! 263: do { \
! 264: void *_p; \
! 265: int _i; \
! 266: RF_LOCK_MUTEX((_fl_)->lock); \
! 267: RF_ASSERT(sizeof(*(_obj_)) == ((_fl_)->obj_size)); \
! 268: if (_fl_->objlist) { \
! 269: _obj_ = _cast_((_fl_)->objlist); \
! 270: (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
! 271: (_fl_)->free_cnt--; \
! 272: } \
! 273: else { \
! 274: /* \
! 275: * Allocate one at a time so we can free \
! 276: * one at a time without cleverness when arena \
! 277: * is full. \
! 278: */ \
! 279: RF_Calloc(_obj_, 1, (_fl_)->obj_size, _cast_); \
! 280: if (_obj_) { \
! 281: if (_init_(_obj_)) { \
! 282: RF_Free(_obj_, (_fl_)->obj_size); \
! 283: _obj_ = NULL; \
! 284: } \
! 285: else { \
! 286: for (_i = 1; _i < (_fl_)->obj_inc; \
! 287: _i++) { \
! 288: RF_Calloc(_p, 1, \
! 289: (_fl_)->obj_size, \
! 290: (void *)); \
! 291: if (_p) { \
! 292: if (_init_(_p)) { \
! 293: RF_Free(_p, \
! 294: (_fl_)->obj_size); \
! 295: _p = NULL; \
! 296: break; \
! 297: } \
! 298: (_cast_(_p))->_nextp_ = \
! 299: (_fl_)->objlist; \
! 300: (_fl_)->objlist = _p; \
! 301: } \
! 302: else { \
! 303: break; \
! 304: } \
! 305: } \
! 306: } \
! 307: } \
! 308: RF_FREELIST_STAT_GROW(_fl_); \
! 309: } \
! 310: RF_FREELIST_STAT_ALLOC(_fl_); \
! 311: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 312: } while (0)
! 313:
! 314: /*
! 315: * fl = FreeList.
! 316: * obj = Object to allocate.
! 317: * nextp = Name of "next" pointer in obj.
! 318: * cast = Cast of obj assignment.
! 319: * init = Init obj func.
! 320: * arg = Arg to init obj func.
! 321: */
! 322: #define RF_FREELIST_GET_INIT_ARG(_fl_,_obj_,_nextp_,_cast_,_init_,_arg_) \
! 323: do { \
! 324: void *_p; \
! 325: int _i; \
! 326: RF_LOCK_MUTEX((_fl_)->lock); \
! 327: RF_ASSERT(sizeof(*(_obj_)) == ((_fl_)->obj_size)); \
! 328: if (_fl_->objlist) { \
! 329: _obj_ = _cast_((_fl_)->objlist); \
! 330: (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
! 331: (_fl_)->free_cnt--; \
! 332: } \
! 333: else { \
! 334: /* \
! 335: * Allocate one at a time so we can free \
! 336: * one at a time without cleverness when arena \
! 337: * is full. \
! 338: */ \
! 339: RF_Calloc(_obj_, 1, (_fl_)->obj_size, _cast_); \
! 340: if (_obj_) { \
! 341: if (_init_(_obj_, _arg_)) { \
! 342: RF_Free(_obj_, (_fl_)->obj_size); \
! 343: _obj_ = NULL; \
! 344: } \
! 345: else { \
! 346: for (_i = 1; _i < (_fl_)->obj_inc; \
! 347: _i++) { \
! 348: RF_Calloc(_p, 1, \
! 349: (_fl_)->obj_size, (void *)); \
! 350: if (_p) { \
! 351: if (_init_(_p, _arg_)) \
! 352: { \
! 353: RF_Free(_p, \
! 354: (_fl_)->obj_size); \
! 355: _p = NULL; \
! 356: break; \
! 357: } \
! 358: (_cast_(_p))->_nextp_ = \
! 359: (_fl_)->objlist; \
! 360: (_fl_)->objlist = _p; \
! 361: } \
! 362: else { \
! 363: break; \
! 364: } \
! 365: } \
! 366: } \
! 367: } \
! 368: RF_FREELIST_STAT_GROW(_fl_); \
! 369: } \
! 370: RF_FREELIST_STAT_ALLOC(_fl_); \
! 371: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 372: } while (0)
! 373:
! 374: /*
! 375: * fl = FreeList.
! 376: * obj = Object to allocate.
! 377: * nextp = Name of "next" pointer in obj.
! 378: * cast = Cast of obj assignment.
! 379: * init = Init obj func.
! 380: */
! 381: #define RF_FREELIST_GET_INIT_NOUNLOCK(_fl_,_obj_,_nextp_,_cast_,_init_) \
! 382: do { \
! 383: void *_p; \
! 384: int _i; \
! 385: RF_LOCK_MUTEX((_fl_)->lock); \
! 386: RF_ASSERT(sizeof(*(_obj_)) == ((_fl_)->obj_size)); \
! 387: if (_fl_->objlist) { \
! 388: _obj_ = _cast_((_fl_)->objlist); \
! 389: (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
! 390: (_fl_)->free_cnt--; \
! 391: } \
! 392: else { \
! 393: /* \
! 394: * Allocate one at a time so we can free \
! 395: * one at a time without cleverness when arena \
! 396: * is full. \
! 397: */ \
! 398: RF_Calloc(_obj_, 1, (_fl_)->obj_size, _cast_); \
! 399: if (_obj_) { \
! 400: if (_init_(_obj_)) { \
! 401: RF_Free(_obj_, (_fl_)->obj_size); \
! 402: _obj_ = NULL; \
! 403: } \
! 404: else { \
! 405: for (_i = 1; _i < (_fl_)->obj_inc; \
! 406: _i++) { \
! 407: RF_Calloc(_p, 1, \
! 408: (_fl_)->obj_size, \
! 409: (void *)); \
! 410: if (_p) { \
! 411: if (_init_(_p)) { \
! 412: RF_Free(_p, \
! 413: (_fl_)->obj_size); \
! 414: _p = NULL; \
! 415: break; \
! 416: } \
! 417: (_cast_(_p))->_nextp_ = \
! 418: (_fl_)->objlist; \
! 419: (_fl_)->objlist = _p; \
! 420: } \
! 421: else { \
! 422: break; \
! 423: } \
! 424: } \
! 425: } \
! 426: } \
! 427: RF_FREELIST_STAT_GROW(_fl_); \
! 428: } \
! 429: RF_FREELIST_STAT_ALLOC(_fl_); \
! 430: } while (0)
! 431:
! 432: /*
! 433: * fl = FreeList.
! 434: * obj = Object to allocate.
! 435: * nextp = Name of "next" pointer in obj.
! 436: * cast = Cast of obj assignment.
! 437: */
! 438: #define RF_FREELIST_GET(_fl_,_obj_,_nextp_,_cast_) \
! 439: do { \
! 440: void *_p; \
! 441: int _i; \
! 442: RF_LOCK_MUTEX((_fl_)->lock); \
! 443: RF_ASSERT(sizeof(*(_obj_)) == ((_fl_)->obj_size)); \
! 444: if (_fl_->objlist) { \
! 445: _obj_ = _cast_((_fl_)->objlist); \
! 446: (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
! 447: (_fl_)->free_cnt--; \
! 448: } \
! 449: else { \
! 450: /* \
! 451: * Allocate one at a time so we can free \
! 452: * one at a time without cleverness when arena \
! 453: * is full. \
! 454: */ \
! 455: RF_Calloc(_obj_, 1, (_fl_)->obj_size, _cast_); \
! 456: if (_obj_) { \
! 457: for (_i = 1; _i < (_fl_)->obj_inc; _i++) { \
! 458: RF_Calloc(_p, 1, (_fl_)->obj_size, \
! 459: (void *)); \
! 460: if (_p) { \
! 461: (_cast_(_p))->_nextp_ = \
! 462: (_fl_)->objlist; \
! 463: (_fl_)->objlist = _p; \
! 464: } \
! 465: else { \
! 466: break; \
! 467: } \
! 468: } \
! 469: } \
! 470: RF_FREELIST_STAT_GROW(_fl_); \
! 471: } \
! 472: RF_FREELIST_STAT_ALLOC(_fl_); \
! 473: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 474: } while (0)
! 475:
! 476: /*
! 477: * fl = FreeList.
! 478: * obj = Object to allocate.
! 479: * nextp = Name of "next" pointer in obj.
! 480: * cast = Cast of obj assignment.
! 481: * num = Num objs to return.
! 482: */
! 483: #define RF_FREELIST_GET_N(_fl_,_obj_,_nextp_,_cast_,_num_) \
! 484: do { \
! 485: void *_p, *_l, *_f; \
! 486: int _i, _n; \
! 487: _l = _f = NULL; \
! 488: _n = 0; \
! 489: RF_LOCK_MUTEX((_fl_)->lock); \
! 490: RF_ASSERT(sizeof(*(_obj_)) == ((_fl_)->obj_size)); \
! 491: for (_n = 0; _n < _num_; _n++) { \
! 492: if (_fl_->objlist) { \
! 493: _obj_ = _cast_((_fl_)->objlist); \
! 494: (_fl_)->objlist = (void *)((_obj_)->_nextp_); \
! 495: (_fl_)->free_cnt--; \
! 496: } \
! 497: else { \
! 498: /* \
! 499: * Allocate one at a time so we can free \
! 500: * one at a time without cleverness when arena \
! 501: * is full. \
! 502: */ \
! 503: RF_Calloc(_obj_, 1, (_fl_)->obj_size, _cast_); \
! 504: if (_obj_) { \
! 505: for (_i = 1; _i < (_fl_)->obj_inc; \
! 506: _i++) { \
! 507: RF_Calloc(_p, 1, \
! 508: (_fl_)->obj_size, \
! 509: (void *)); \
! 510: if (_p) { \
! 511: (_cast_(_p))->_nextp_ = \
! 512: (_fl_)->objlist; \
! 513: (_fl_)->objlist = _p; \
! 514: } \
! 515: else { \
! 516: break; \
! 517: } \
! 518: } \
! 519: } \
! 520: RF_FREELIST_STAT_GROW(_fl_); \
! 521: } \
! 522: if (_f == NULL) \
! 523: _f = _obj_; \
! 524: if (_obj_) { \
! 525: (_cast_(_obj_))->_nextp_ = _l; \
! 526: _l = _obj_; \
! 527: RF_FREELIST_STAT_ALLOC(_fl_); \
! 528: } \
! 529: else { \
! 530: (_cast_(_f))->_nextp_ = (_fl_)->objlist; \
! 531: (_fl_)->objlist = _l; \
! 532: _n = _num_; \
! 533: } \
! 534: } \
! 535: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 536: } while (0)
! 537:
! 538: /*
! 539: * fl = FreeList.
! 540: * obj = Object to free.
! 541: * nextp = Name of "next" pointer in obj.
! 542: */
! 543: #define RF_FREELIST_FREE(_fl_,_obj_,_nextp_) \
! 544: do { \
! 545: RF_LOCK_MUTEX((_fl_)->lock); \
! 546: if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
! 547: RF_Free(_obj_, (_fl_)->obj_size); \
! 548: } \
! 549: else { \
! 550: RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
! 551: (_obj_)->_nextp_ = (_fl_)->objlist; \
! 552: (_fl_)->objlist = (void *)(_obj_); \
! 553: (_fl_)->free_cnt++; \
! 554: } \
! 555: RF_FREELIST_STAT_FREE(_fl_); \
! 556: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 557: } while (0)
! 558:
! 559: /*
! 560: * fl = FreeList.
! 561: * obj = Object to free.
! 562: * nextp = Name of "next" pointer in obj.
! 563: * num = Num to free (debugging).
! 564: */
! 565: #define RF_FREELIST_FREE_N(_fl_,_obj_,_nextp_,_cast_,_num_) \
! 566: do { \
! 567: void *_no; \
! 568: int _n; \
! 569: _n = 0; \
! 570: RF_LOCK_MUTEX((_fl_)->lock); \
! 571: while(_obj_) { \
! 572: _no = (_cast_(_obj_))->_nextp_; \
! 573: if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
! 574: RF_Free(_obj_, (_fl_)->obj_size); \
! 575: } \
! 576: else { \
! 577: RF_ASSERT((_fl_)->free_cnt < \
! 578: (_fl_)->max_free_cnt); \
! 579: (_obj_)->_nextp_ = (_fl_)->objlist; \
! 580: (_fl_)->objlist = (void *)(_obj_); \
! 581: (_fl_)->free_cnt++; \
! 582: } \
! 583: _n++; \
! 584: _obj_ = _no; \
! 585: RF_FREELIST_STAT_FREE(_fl_); \
! 586: } \
! 587: RF_ASSERT(_n==(_num_)); \
! 588: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 589: } while (0)
! 590:
! 591: /*
! 592: * fl = FreeList.
! 593: * obj = Object to free.
! 594: * nextp = Name of "next" pointer in obj.
! 595: * clean = Undo for init.
! 596: */
! 597: #define RF_FREELIST_FREE_CLEAN(_fl_,_obj_,_nextp_,_clean_) \
! 598: do { \
! 599: RF_LOCK_MUTEX((_fl_)->lock); \
! 600: if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
! 601: _clean_(_obj_); \
! 602: RF_Free(_obj_, (_fl_)->obj_size); \
! 603: } \
! 604: else { \
! 605: RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
! 606: (_obj_)->_nextp_ = (_fl_)->objlist; \
! 607: (_fl_)->objlist = (void *)(_obj_); \
! 608: (_fl_)->free_cnt++; \
! 609: } \
! 610: RF_FREELIST_STAT_FREE(_fl_); \
! 611: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 612: } while (0)
! 613:
! 614: /*
! 615: * fl = FreeList.
! 616: * obj = Object to free.
! 617: * nextp = Name of "next" pointer in obj.
! 618: * clean = Undo for init.
! 619: * arg = Arg for undo func.
! 620: */
! 621: #define RF_FREELIST_FREE_CLEAN_ARG(_fl_,_obj_,_nextp_,_clean_,_arg_) \
! 622: do { \
! 623: RF_LOCK_MUTEX((_fl_)->lock); \
! 624: if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
! 625: _clean_(_obj_, _arg_); \
! 626: RF_Free(_obj_, (_fl_)->obj_size); \
! 627: } \
! 628: else { \
! 629: RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
! 630: (_obj_)->_nextp_ = (_fl_)->objlist; \
! 631: (_fl_)->objlist = (void *)(_obj_); \
! 632: (_fl_)->free_cnt++; \
! 633: } \
! 634: RF_FREELIST_STAT_FREE(_fl_); \
! 635: RF_UNLOCK_MUTEX((_fl_)->lock); \
! 636: } while (0)
! 637:
! 638: /*
! 639: * fl = FreeList.
! 640: * obj = Object to free.
! 641: * nextp = Name of "next" pointer in obj.
! 642: * clean = Undo for init.
! 643: */
! 644: #define RF_FREELIST_FREE_CLEAN_NOUNLOCK(_fl_,_obj_,_nextp_,_clean_) \
! 645: do { \
! 646: RF_LOCK_MUTEX((_fl_)->lock); \
! 647: if ((_fl_)->free_cnt == (_fl_)->max_free_cnt) { \
! 648: _clean_(_obj_); \
! 649: RF_Free(_obj_, (_fl_)->obj_size); \
! 650: } \
! 651: else { \
! 652: RF_ASSERT((_fl_)->free_cnt < (_fl_)->max_free_cnt); \
! 653: (_obj_)->_nextp_ = (_fl_)->objlist; \
! 654: (_fl_)->objlist = (void *)(_obj_); \
! 655: (_fl_)->free_cnt++; \
! 656: } \
! 657: RF_FREELIST_STAT_FREE(_fl_); \
! 658: } while (0)
! 659:
! 660: /*
! 661: * fl = FreeList.
! 662: * nextp = Name of "next" pointer in obj.
! 663: * cast = Cast to object type.
! 664: */
! 665: #define RF_FREELIST_DESTROY(_fl_,_nextp_,_cast_) \
! 666: do { \
! 667: void *_cur, *_next; \
! 668: RF_FREELIST_STAT_REPORT(_fl_); \
! 669: rf_mutex_destroy(&((_fl_)->lock)); \
! 670: for (_cur = (_fl_)->objlist; _cur; _cur = _next) { \
! 671: _next = (_cast_ _cur)->_nextp_; \
! 672: RF_Free(_cur, (_fl_)->obj_size); \
! 673: } \
! 674: RF_Free(_fl_, sizeof(RF_FreeList_t)); \
! 675: } while (0)
! 676:
! 677: /*
! 678: * fl = FreeList.
! 679: * nextp = Name of "next" pointer in obj.
! 680: * cast = Cast to object type.
! 681: * clean = Func to undo obj init.
! 682: */
! 683: #define RF_FREELIST_DESTROY_CLEAN(_fl_,_nextp_,_cast_,_clean_) \
! 684: do { \
! 685: void *_cur, *_next; \
! 686: RF_FREELIST_STAT_REPORT(_fl_); \
! 687: rf_mutex_destroy(&((_fl_)->lock)); \
! 688: for (_cur = (_fl_)->objlist; _cur; _cur = _next) { \
! 689: _next = (_cast_ _cur)->_nextp_; \
! 690: _clean_(_cur); \
! 691: RF_Free(_cur, (_fl_)->obj_size); \
! 692: } \
! 693: RF_Free(_fl_, sizeof(RF_FreeList_t)); \
! 694: } while (0)
! 695:
! 696: /*
! 697: * fl = FreeList.
! 698: * nextp = Name of "next" pointer in obj.
! 699: * cast = Cast to object type.
! 700: * clean = Func to undo obj init.
! 701: * arg = Arg for undo func.
! 702: */
! 703: #define RF_FREELIST_DESTROY_CLEAN_ARG(_fl_,_nextp_,_cast_,_clean_,_arg_) \
! 704: do { \
! 705: void *_cur, *_next; \
! 706: RF_FREELIST_STAT_REPORT(_fl_); \
! 707: rf_mutex_destroy(&((_fl_)->lock)); \
! 708: for (_cur = (_fl_)->objlist; _cur; _cur = _next) { \
! 709: _next = (_cast_ _cur)->_nextp_; \
! 710: _clean_(_cur, _arg_); \
! 711: RF_Free(_cur, (_fl_)->obj_size); \
! 712: } \
! 713: RF_Free(_fl_, sizeof(RF_FreeList_t)); \
! 714: } while (0)
! 715:
! 716: #endif /* !_RF__RF_FREELIST_H_ */
CVSweb