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