1 static char rcsid[] = "$Id: hitlistpool.c 218195 2019-01-17 13:53:13Z twu $";
2 #ifdef HAVE_CONFIG_H
3 #include <config.h>
4 #endif
5
6 #include "hitlistpool.h"
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include "mem.h"
10
11
12 /* Same as Listpool_T. Currently used for lists of Stage3end_T and
13 Stage3pair_T objects */
14
15
16 #define CHUNKSIZE 16384
17
18 #ifdef DEBUG
19 #define debug(x) x
20 #else
21 #define debug(x)
22 #endif
23
24 /* For mechanics of memory allocation and deallocation */
25 #ifdef DEBUG1
26 #define debug1(x) x
27 #else
28 #define debug1(x)
29 #endif
30
31
32 #define T Hitlistpool_T
33 struct T {
34 int nlistcells;
35 int listcellctr;
36 struct List_T *listcellptr;
37 List_T chunks;
38 };
39
40 void
Hitlistpool_free_memory(T this)41 Hitlistpool_free_memory (T this) {
42 List_T p;
43 struct List_T *listcellptr;
44
45 for (p = this->chunks; p != NULL; p = List_next(p)) {
46 listcellptr = (struct List_T *) List_head(p);
47 FREE_KEEP(listcellptr);
48 }
49 List_free_keep(&this->chunks);
50
51 this->nlistcells = 0;
52 this->listcellctr = 0;
53 this->chunks = NULL;
54 /* this->listcellptr = add_new_listcellchunk(this); */
55
56 return;
57 }
58
59 void
Hitlistpool_free(T * old)60 Hitlistpool_free (T *old) {
61 Hitlistpool_free_memory(*old);
62 FREE_KEEP(*old);
63 return;
64 }
65
66
67
68 static struct List_T *
add_new_chunk(T this)69 add_new_chunk (T this) {
70 struct List_T *chunk;
71
72 chunk = (struct List_T *) MALLOC_KEEP(CHUNKSIZE*sizeof(struct List_T));
73 this->chunks = List_push_keep(this->chunks,(void *) chunk);
74 debug1(printf("Adding a new chunk of listcells. Ptr for listcell %d is %p\n",
75 this->nlistcells,chunk));
76
77 this->nlistcells += CHUNKSIZE;
78 return chunk;
79 }
80
81 T
Hitlistpool_new(void)82 Hitlistpool_new (void) {
83 T new = (T) MALLOC_KEEP(sizeof(*new));
84
85 new->nlistcells = 0;
86 new->listcellctr = 0;
87 new->chunks = NULL;
88 /* new->listcellptr = add_new_listcellchunk(new); */
89
90 return new;
91 }
92
93 void
Hitlistpool_reset(T this)94 Hitlistpool_reset (T this) {
95 this->listcellctr = 0;
96 return;
97 }
98
99 #ifdef DEBUG_HITLISTPOOL
100 List_T
Hitlist_push_actual(List_T list,T this,void * contents,const char * file,int line)101 Hitlist_push_actual (List_T list, T this, void *contents,
102 const char *file, int line) {
103 List_T listcell;
104 List_T p;
105 int n;
106
107 if (this->listcellctr >= this->nlistcells) {
108 this->listcellptr = add_new_chunk(this);
109 } else if ((this->listcellctr % CHUNKSIZE) == 0) {
110 for (n = this->nlistcells - CHUNKSIZE, p = this->chunks;
111 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
112 this->listcellptr = (struct List_T *) p->first;
113 debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
114 }
115 listcell = this->listcellptr++;
116 this->listcellctr++;
117
118 listcell->first = contents;
119 listcell->rest = list;
120
121 printf("Allocating %p to %p -- Malloc of 1 bytes requested from %s:%d\n",
122 listcell,listcell,file,line);
123 return listcell;
124 }
125
126 #else
127 List_T
Hitlist_push(List_T list,T this,void * contents)128 Hitlist_push (List_T list, T this, void *contents) {
129 List_T listcell;
130 List_T p;
131 int n;
132
133 if (this->listcellctr >= this->nlistcells) {
134 this->listcellptr = add_new_chunk(this);
135 } else if ((this->listcellctr % CHUNKSIZE) == 0) {
136 for (n = this->nlistcells - CHUNKSIZE, p = this->chunks;
137 n > this->listcellctr; p = p->rest, n -= CHUNKSIZE) ;
138 this->listcellptr = (struct List_T *) p->first;
139 debug1(printf("Located listcell %d at %p\n",this->listcellctr,this->listcellptr));
140 }
141 listcell = this->listcellptr++;
142 this->listcellctr++;
143
144 listcell->first = contents;
145 listcell->rest = list;
146
147 return listcell;
148 }
149 #endif
150
151
152 #ifdef DEBUG_HITLISTPOOL
153 void
Hitlist_free_actual(List_T * old,const char * file,int line)154 Hitlist_free_actual (List_T *old, const char *file, int line) {
155 List_T p;
156
157 for (p = *old; p != NULL; p = List_next(p)) {
158 printf("Freeing %p in standard pool at %s:%d\n",p,file,line);
159 }
160 *old = (List_T) NULL;
161 return;
162 }
163
164 #elif !defined(HAVE_INLINE)
165 void
Hitlist_free(List_T * old)166 Hitlist_free (List_T *old) {
167 *old = (List_T) NULL;
168 return;
169 }
170 #endif
171
172 List_T
Hitlist_pop(List_T list,void ** contents)173 Hitlist_pop (List_T list, void **contents) {
174 List_T head;
175
176 if (list != NULL) {
177 head = list->rest;
178 *contents = list->first;
179 return head;
180 } else {
181 return list;
182 }
183 }
184
185
186 List_T
Hitlist_copy(List_T source,T this)187 Hitlist_copy (List_T source, T this) {
188 List_T dest = NULL;
189
190 while (source != NULL) {
191 dest = Hitlist_push(dest,this,/*orig*/source->first);
192 source = source->rest;
193 }
194 return List_reverse(dest);
195 }
196
197
198