Annotation of parser3/src/targets/isapi/pool_storage.h, revision 1.13
1.1 paf 1: /** @file
2: Parser: ISAPI: pool storage class decl.
3:
4: Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
1.13 ! paf 5: Author: Alexander Petrosyan <paf@design.ru> (http://paf.design.ru)
1.1 paf 6:
1.13 ! paf 7: $Id: pool_storage.h,v 1.12 2001/10/24 16:52:25 parser Exp $
1.1 paf 8: */
9:
10: #ifndef PA_POOL_STORAGE_H
11: #define PA_POOL_STORAGE_H
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.8 parser 83: cleanups(100),
84: allocations(10*0x400) {
1.1 paf 85: }
86:
1.7 parser 87: void *malloc(size_t size) {
88: void *result=::malloc(size);
89: if(result && !allocations.add(result)) {
90: ::free(result); result=0;
91: }
92: return result;
93: }
94: void *calloc(size_t size) {
95: void *result=::calloc(size, 1);
96: if(result && !allocations.add(result)) {
97: ::free(result); result=0;
98: }
99: return result;
100: }
1.1 paf 101:
1.6 parser 102: bool register_cleanup(void (*cleanup) (void *), void *data) {
103: Cleanup_struct item={cleanup, data};
1.7 parser 104: return cleanups.add(item)!=0;
1.1 paf 105: }
106:
1.12 parser 107: static void cleanup(Cleanup_struct& item) {
108: item.cleanup(item.data);
109: }
110:
111: static void free(void *& item) {
112: ::free(item); item=0;
113: }
114:
1.6 parser 115: ~Pool_storage() {
1.8 parser 116: // cleanups first, because they use some object's memory pointers
1.12 parser 117: cleanups.for_each_reverse(cleanup);
1.8 parser 118:
119: // allocations
1.12 parser 120: allocations.for_each_reverse(free);
1.5 parser 121: }
122:
1.6 parser 123: private:
1.1 paf 124:
1.8 parser 125: List<Cleanup_struct> cleanups;
1.7 parser 126: List<void *> allocations;
1.1 paf 127:
128: };
129:
130:
131: #endif
E-mail: