[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     ! 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