1 /********************************************************************/ 2 /* */ 3 /* s7 Seed7 interpreter */ 4 /* Copyright (C) 1989 - 2000 Thomas Mertes */ 5 /* */ 6 /* This program is free software; you can redistribute it and/or */ 7 /* modify it under the terms of the GNU General Public License as */ 8 /* published by the Free Software Foundation; either version 2 of */ 9 /* the License, or (at your option) any later version. */ 10 /* */ 11 /* This program is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 14 /* GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public */ 17 /* License along with this program; if not, write to the */ 18 /* Free Software Foundation, Inc., 51 Franklin Street, */ 19 /* Fifth Floor, Boston, MA 02110-1301, USA. */ 20 /* */ 21 /* Module: General */ 22 /* File: seed7/src/flistutl.h */ 23 /* Changes: 1993, 1994 Thomas Mertes */ 24 /* Content: Procedures for free memory list maintenance. */ 25 /* */ 26 /********************************************************************/ 27 28 typedef struct { 29 objectType objects; 30 listType list_elems; 31 nodeType nodes; 32 inFileType infiles; 33 } freeListRootType; 34 35 #ifdef DO_INIT 36 freeListRootType flist = {NULL, NULL, NULL, NULL}; 37 #else 38 EXTERN freeListRootType flist; 39 #endif 40 41 42 #if DO_HEAP_LOG 43 #define F_LOG1(X) printf("\nlalloc(%u) -> %ld\n", sizeof(*X), (long) X), 44 #define F_LOG2(X) printf("\nlfree(%u) <- %ld\n", sizeof(*X), (long) X), 45 #else 46 #define F_LOG1(X) 47 #define F_LOG2(X) 48 #endif 49 50 #if USE_CHUNK_ALLOCS 51 #define ALIGN(size) (((((size) - 1) >> MALLOC_ALIGNMENT) + 1) << MALLOC_ALIGNMENT) 52 #if USE_ALTERNATE_CHUNK_ALLOCS 53 #define OLD_CHUNK(var,tp,byt) (var = (tp) chunk.freemem, chunk.freemem += (byt), TRUE) 54 #define NEW_CHUNK(var,tp,byt) ((var = (tp) heap_chunk(byt)) != NULL) 55 #define ALLOC_CHUNK(var,tp,byt) ((byt) > chunk.beyond - chunk.freemem ? NEW_CHUNK(var, tp, byt) : OLD_CHUNK(var, tp, byt)) 56 #define FREE_CHUNK(var,byt) (chunk.lost_bytes += (byt)) 57 #else 58 #define OLD_CHUNK(var,tp,byt) (var = (tp) chunk.freemem, chunk.freemem += (byt), chunk.size -= (byt), TRUE) 59 #define NEW_CHUNK(var,tp,byt) ((var = (tp) heap_chunk(byt)) != NULL) 60 #define ALLOC_CHUNK(var,tp,byt) ((byt) > chunk.size ? NEW_CHUNK(var, tp, byt) : OLD_CHUNK(var, tp, byt)) 61 #define FREE_CHUNK(var,byt) (chunk.lost_bytes += (byt)) 62 #endif 63 #else 64 #endif 65 66 67 #if USE_CHUNK_ALLOCS 68 #define ALLOC_ID_NAME(var,len) ALLOC_CHUNK(var, ustriType, ALIGN(SIZ_USTRI(len))) 69 #define FREE_ID_NAME(var,len) (CNT(CNT2_USTRI(len, SIZ_USTRI(len), count.idt, count.idt_bytes)) FREE_CHUNK(var, ALIGN(SIZ_USTRI(len)))) 70 #else 71 #define ALLOC_ID_NAME(var,len) ALLOC_HEAP(var, ustriType, SIZ_USTRI(len)) 72 #define FREE_ID_NAME(var,len) (CNT(CNT2_USTRI(len, SIZ_USTRI(len), count.idt, count.idt_bytes)) FREE_HEAP(var, SIZ_USTRI(len))) 73 #endif 74 #define COUNT_ID_NAME(len) CNT1_USTRI((len), SIZ_USTRI(len), count.idt, count.idt_bytes) 75 76 #if USE_CHUNK_ALLOCS 77 #define ALLOC_FLISTELEM(var,rec) ALLOC_CHUNK(var, rec *, ALIGN(SIZ_REC(rec))) 78 #else 79 #define ALLOC_FLISTELEM(var,rec) ALLOC_HEAP(var, rec *, SIZ_REC(rec)) 80 #endif 81 82 #define COUNT_FLISTELEM(rec,cnt) CNT1_REC(SIZ_REC(rec), cnt) 83 84 85 #define HEAP_OBJ(O,T) (!ALLOC_FLISTELEM(O, T) ? FALSE : (CNT(COUNT_FLISTELEM(T, count.object)) TRUE)) 86 #define HEAP_L_E(L,T) (!ALLOC_FLISTELEM(L, T) ? FALSE : (CNT(COUNT_FLISTELEM(T, count.list_elem)) TRUE)) 87 #define HEAP_NODE(N,T) (!ALLOC_FLISTELEM(N, T) ? FALSE : (CNT(COUNT_FLISTELEM(T, count.node)) TRUE)) 88 #define HEAP_FILE(F,T) (!ALLOC_FLISTELEM(F, T) ? FALSE : (CNT(COUNT_FLISTELEM(T, count.infil)) TRUE)) 89 90 #define POP_OBJ(O) (O = flist.objects, flist.objects = flist.objects->value.objValue, F_LOG1(O) TRUE) 91 #define POP_L_E(L) (L = flist.list_elems, flist.list_elems = flist.list_elems->next, F_LOG1(L) TRUE) 92 #define POP_NODE(N) (N = flist.nodes, flist.nodes = flist.nodes->next1, F_LOG1(N) TRUE) 93 #define POP_FILE(F) (F = flist.infiles, flist.infiles = flist.infiles->next, F_LOG1(F) TRUE) 94 95 96 #if WITH_OBJECT_FREELIST 97 #define ALLOC_OBJECT(O) (flist.objects != NULL ? POP_OBJ(O) : HEAP_OBJ(O, objectRecord)) 98 #define FREE_OBJECT(O) (F_LOG2(O) (O)->value.objValue = flist.objects, (O)->objcategory = 0, flist.objects = (O)) 99 /* #define FREE_OBJECT(O) (printf("FREE_OBJECT(%lu)\n", O), F_LOG2(O) (O)->value.objValue = flist.objects, (O)->objcategory = 0, flist.objects = (O)) */ 100 /* #define FREE_OBJECT(O) (F_LOG2(O) check_obj_flist(O) ? ((O)->value.objValue=flist.objects,(O)->objcategory=0,flist.objects=(O)) : NULL) */ 101 #else 102 #define ALLOC_OBJECT(O) HEAP_OBJ(O, objectRecord) 103 #define FREE_OBJECT(O) FREE_RECORD(O, objectRecord, count.object) 104 #if USE_CHUNK_ALLOCS 105 #error Configuration error: USE_CHUNK_ALLOCS needs WITH_OBJECT_FREELIST 106 #endif 107 #endif 108 109 #if WITH_LIST_FREELIST 110 #define ALLOC_L_ELEM(L) (flist.list_elems != NULL ? POP_L_E(L) : HEAP_L_E(L, listRecord)) 111 #define FREE_L_ELEM(L) (F_LOG2(L) (L)->next = flist.list_elems, flist.list_elems = (L)) 112 #else 113 #define ALLOC_L_ELEM(L) HEAP_L_E(L, listRecord) 114 #define FREE_L_ELEM(L) FREE_RECORD(L, listRecord, count.list_elem) 115 #if USE_CHUNK_ALLOCS 116 #error Configuration error: USE_CHUNK_ALLOCS needs WITH_LIST_FREELIST 117 #endif 118 #endif 119 120 #if WITH_NODE_FREELIST 121 #define ALLOC_NODE(N) (flist.nodes != NULL ? POP_NODE(N) : HEAP_NODE(N, nodeRecord)) 122 #define FREE_NODE(N) (F_LOG2(N) (N)->next1 = flist.nodes, flist.nodes = (N)) 123 #else 124 #define ALLOC_NODE(N) HEAP_NODE(N, nodeRecord) 125 #define FREE_NODE(N) FREE_RECORD(N, nodeRecord, count.node) 126 #if USE_CHUNK_ALLOCS 127 #error Configuration error: USE_CHUNK_ALLOCS needs WITH_NODE_FREELIST 128 #endif 129 #endif 130 131 #if WITH_FILE_FREELIST 132 #define ALLOC_FILE(F) (flist.infiles != NULL ? POP_FILE(F) : HEAP_FILE(F, inFileRecord)) 133 #define FREE_FILE(F) (F_LOG2(F) (F)->next = flist.infiles, flist.infiles = (F)) 134 #else 135 #define ALLOC_FILE(F) HEAP_FILE(F, inFileRecord) 136 #define FREE_FILE(F) FREE_RECORD(F, inFileRecord, count.infil) 137 #if USE_CHUNK_ALLOCS 138 #error Configuration error: USE_CHUNK_ALLOCS needs WITH_FILE_FREELIST 139 #endif 140 #endif 141 142 143 #if DO_HEAP_STATISTIC 144 void heapStatistic (void); 145 #endif 146 memSizeType heapsize (void); 147 #if USE_CHUNK_ALLOCS 148 #ifdef USE_FLIST_ALLOC 149 void *flist_alloc (size_t); 150 #endif 151 #else 152 void reuse_free_lists (void); 153 #endif 154 #if USE_CHUNK_ALLOCS 155 void *heap_chunk (size_t); 156 #endif 157