This source file includes following definitions.
- RF_FreeListStats_t
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
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
123
124 struct RF_FreeList_s {
125 void *objlist;
126 int free_cnt;
127 int max_free_cnt;
128 int obj_inc;
129 int obj_size;
130 RF_DECLARE_MUTEX(lock);
131 #if RF_FREELIST_STATS > 0
132 RF_FreeListStats_t stats;
133 #endif
134 };
135
136
137
138
139
140
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
162
163
164
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
194
195
196
197
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
225
226
227
228
229
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
257
258
259
260
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
276
277
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
316
317
318
319
320
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
336
337
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
376
377
378
379
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
395
396
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
434
435
436
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
452
453
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
478
479
480
481
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
500
501
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
540
541
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
561
562
563
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
593
594
595
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
616
617
618
619
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
640
641
642
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
662
663
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
679
680
681
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
698
699
700
701
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