|
|
1.1 paf 1: /** @file
2: Parser: ISAPI: pool storage class decl.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
5:
6: Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
7:
1.8 ! parser 8: $Id: pool_storage.h,v 1.7 2001/09/15 13:34:33 parser Exp $
1.1 paf 9: */
10:
11: #ifndef PA_POOL_STORAGE_H
12: #define PA_POOL_STORAGE_H
13:
14: #include "pa_config_includes.h"
15:
16: /**
17: Dumb pool allocations accounter
18:
1.4 paf 19: @todo implement at least simple suballocations
1.1 paf 20: */
21: class Pool_storage {
1.6 parser 22:
1.7 parser 23: template<typename T> class List {
1.6 parser 24: friend Pool_storage;
25: public:
1.7 parser 26: List(int preallocate) :
27: items((T *)::malloc(preallocate*sizeof(T))),
28: allocated(0),
29: used(0) {
1.6 parser 30: if(items) // successfully preallocated?
1.7 parser 31: allocated=preallocate;
1.6 parser 32: }
33:
34: ~List() {
1.7 parser 35: ::free(items);
1.6 parser 36: }
37:
1.7 parser 38: bool add(T item) {
1.6 parser 39: if(full())
40: if(!expand())
1.7 parser 41: return false;
1.6 parser 42:
1.7 parser 43: items[used++]=item;
44: return true;
1.6 parser 45: }
46:
47: private:
48:
1.7 parser 49: bool full() { return used==allocated; }
1.6 parser 50: bool expand() {
1.7 parser 51: size_t new_allocated=allocated*3/2;
52: T *new_items=(T *)::realloc(items, new_allocated*sizeof(T));
1.6 parser 53: if(new_items) {
54: items=new_items;
1.7 parser 55: allocated=new_allocated;
1.6 parser 56: return true;
57: } else
58: return false;
59: }
60:
61: private:
62:
1.7 parser 63: T *items;
64: size_t allocated;
65: size_t used;
1.6 parser 66:
67: };
68:
69: struct Cleanup_struct {
70: void (*cleanup) (void *);
71: void *data;
72: };
73:
74:
1.1 paf 75: public:
76:
1.6 parser 77: Pool_storage() :
1.8 ! parser 78: cleanups(100),
! 79: allocations(10*0x400) {
1.1 paf 80: }
81:
1.7 parser 82: void *malloc(size_t size) {
83: void *result=::malloc(size);
84: if(result && !allocations.add(result)) {
85: ::free(result); result=0;
86: }
87: return result;
88: }
89: void *calloc(size_t size) {
90: void *result=::calloc(size, 1);
91: if(result && !allocations.add(result)) {
92: ::free(result); result=0;
93: }
94: return result;
95: }
1.1 paf 96:
1.6 parser 97: bool register_cleanup(void (*cleanup) (void *), void *data) {
98: Cleanup_struct item={cleanup, data};
1.7 parser 99: return cleanups.add(item)!=0;
1.1 paf 100: }
101:
1.6 parser 102: ~Pool_storage() {
103: size_t i;
1.5 parser 104:
1.8 ! parser 105: // cleanups first, because they use some object's memory pointers
! 106: // Cleanup_structs
1.7 parser 107: for(i=0; i<cleanups.used; i++) {
108: Cleanup_struct& item=cleanups.items[i];
109: item.cleanup(item.data);
1.6 parser 110: }
1.8 ! parser 111:
! 112: // allocations
! 113: for(i=0; i<allocations.used; i++)
! 114: free(allocations.items[i]);
1.5 parser 115: }
116:
1.6 parser 117: private:
1.1 paf 118:
1.8 ! parser 119: List<Cleanup_struct> cleanups;
1.7 parser 120: List<void *> allocations;
1.1 paf 121:
122: };
123:
124:
125: #endif