Annotation of parser3/src/targets/isapi/pool_storage.h, revision 1.18
1.1 paf 1: /** @file
2: Parser: ISAPI: pool storage class decl.
3:
1.14 paf 4: Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.15 paf 5: Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1 paf 6: */
7:
8: #ifndef PA_POOL_STORAGE_H
9: #define PA_POOL_STORAGE_H
1.17 paf 10:
1.18 ! paf 11: static const char* IDENT_POOL_STORAGE_H="$Date: pool_storage.h,v 1.17 2002/08/01 11:26:53 paf Exp $";
1.1 paf 12:
13: #include "pa_config_includes.h"
14:
15: /**
16: Dumb pool allocations accounter
17:
1.4 paf 18: @todo implement at least simple suballocations
1.1 paf 19: */
1.12 parser 20: template<class T> class List {
21: public:
22: List(int preallocate) :
23: items((T *)::malloc(preallocate*sizeof(T))),
24: allocated(0),
25: used(0) {
26: if(items) // successfully preallocated?
27: allocated=preallocate;
28: }
29:
30: ~List() {
31: ::free(items);
32: }
33:
34: bool add(T item) {
35: if(full())
36: if(!expand())
37: return false;
38:
39: items[used++]=item;
40: return true;
41: }
1.6 parser 42:
1.12 parser 43: void for_each_reverse(void (*callback)(T& info)) {
44: size_t top;
1.6 parser 45:
1.12 parser 46: for(top=used; top; )
47: callback(items[--top]);
48: }
1.6 parser 49:
1.12 parser 50: private:
1.6 parser 51:
1.12 parser 52: bool full() { return used==allocated; }
53: bool expand() {
54: size_t new_allocated=allocated*3/2;
55: T *new_items=(T *)::realloc(items, new_allocated*sizeof(T));
56: if(new_items) {
57: items=new_items;
58: allocated=new_allocated;
1.7 parser 59: return true;
1.12 parser 60: } else
61: return false;
62: }
1.6 parser 63:
1.12 parser 64: private:
1.6 parser 65:
1.12 parser 66: T *items;
67: size_t allocated;
68: size_t used;
1.6 parser 69:
1.12 parser 70: };
1.6 parser 71:
1.12 parser 72: class Pool_storage {
1.6 parser 73:
74: struct Cleanup_struct {
75: void (*cleanup) (void *);
76: void *data;
77: };
78:
79:
1.1 paf 80: public:
81:
1.6 parser 82: Pool_storage() :
1.16 paf 83: #ifdef _DEBUG
84: fbreak_on_alloc(false),
85: #endif
1.8 parser 86: cleanups(100),
87: allocations(10*0x400) {
1.1 paf 88: }
89:
1.16 paf 90: void *malloc(size_t size) {
91: #ifdef _DEBUG
92: if(fbreak_on_alloc)
93: _asm int 3;
94: #endif
1.7 parser 95: void *result=::malloc(size);
96: if(result && !allocations.add(result)) {
97: ::free(result); result=0;
98: }
99: return result;
100: }
101: void *calloc(size_t size) {
1.16 paf 102: #ifdef _DEBUG
103: if(fbreak_on_alloc)
104: _asm int 3;
105: #endif
1.7 parser 106: void *result=::calloc(size, 1);
107: if(result && !allocations.add(result)) {
108: ::free(result); result=0;
109: }
110: return result;
111: }
1.1 paf 112:
1.6 parser 113: bool register_cleanup(void (*cleanup) (void *), void *data) {
114: Cleanup_struct item={cleanup, data};
1.7 parser 115: return cleanups.add(item)!=0;
1.1 paf 116: }
117:
1.12 parser 118: static void cleanup(Cleanup_struct& item) {
119: item.cleanup(item.data);
120: }
121:
122: static void free(void *& item) {
123: ::free(item); item=0;
124: }
125:
1.6 parser 126: ~Pool_storage() {
1.8 parser 127: // cleanups first, because they use some object's memory pointers
1.12 parser 128: cleanups.for_each_reverse(cleanup);
1.8 parser 129:
130: // allocations
1.12 parser 131: allocations.for_each_reverse(free);
1.5 parser 132: }
1.16 paf 133:
134: #ifdef _DEBUG
135: public:
136: bool fbreak_on_alloc;
137: #endif
1.5 parser 138:
1.6 parser 139: private:
1.1 paf 140:
1.8 parser 141: List<Cleanup_struct> cleanups;
1.7 parser 142: List<void *> allocations;
1.1 paf 143:
144: };
145:
146:
147: #endif
E-mail: