[BACK]Return to rf_freelist.h CVS log [TXT][DIR] Up to [local] / sys / dev / raidframe

Annotation of sys/dev/raidframe/rf_freelist.h, Revision 1.1.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