root/dev/raidframe/rf_freelist.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. RF_FreeListStats_t

    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_ */

/* [<][>][^][v][top][bottom][index][help] */