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