1 #line 1 "memmgr.c"
2 
3 
4 
5 
6 
7 
8 
9 #line 1 "./memmgr.h"
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
54 
55 
56 
57 
58 
59 
60 
61 
62 
63 
64 
65 
66 
67 
68 
69 
70 
71 
72 
73 
74 
75 
76 
77 
78 
79 
80 
81 typedef unsigned char byte;
82 typedef unsigned long ulong;
83 
84 
85 
86 
87 
88 
89 void memmgr_init();
90 
91 
92 
93 void* memmgr_alloc(ulong nbytes);
94 
95 
96 
97 void memmgr_free(void* ap);
98 
99 
100 
101 
102 void memmgr_print_stats();
103 
104 
105 
106 #line 9 "memmgr.c"
107 
108 typedef ulong Align;
109 
110 union mem_header_union
111 {
112     struct
113     {
114 
115 
116         union mem_header_union* next;
117 
118 
119 
120         ulong size;
121     } s;
122 
123 
124 
125     Align align_dummy;
126 };
127 
128 typedef union mem_header_union mem_header_t;
129 
130 
131 
132 static mem_header_t base;
133 
134 
135 
136 static mem_header_t* freep = 0;
137 
138 
139 
140 static byte pool[8 * 1024] = {0};
141 static ulong pool_free_pos = 0;
142 
143 
memmgr_init()144 void memmgr_init()
145 {
146     base.s.next = 0;
147     base.s.size = 0;
148     freep = 0;
149     pool_free_pos = 0;
150 }
151 
152 
memmgr_print_stats()153 void memmgr_print_stats()
154 {
155 
156     mem_header_t* p;
157 
158     printf("------ Memory manager stats ------\n\n");
159     printf(    "Pool: free_pos = %lu (%lu bytes left)\n\n",
160             pool_free_pos,8 * 1024 - pool_free_pos);
161 
162     p = (mem_header_t*) pool;
163 
164     while (p < (mem_header_t*) (pool + pool_free_pos))
165     {
166         printf(    "  * Addr: 0x%8lu; Size: %8lu\n",
167                 p, p->s.size);
168 
169         p += p->s.size;
170     }
171 
172     printf("\nFree list:\n\n");
173 
174     if (freep)
175     {
176         p = freep;
177 
178         while (1)
179         {
180             printf(    "  * Addr: 0x%8lu; Size: %8lu; Next: 0x%8lu\n",
181                     p, p->s.size, p->s.next);
182 
183             p = p->s.next;
184 
185             if (p == freep)
186                 break;
187         }
188     }
189     else
190     {
191         printf("Empty\n");
192     }
193 
194     printf("\n");
195 
196 }
197 
198 
get_mem_from_pool(ulong nquantas)199 static mem_header_t* get_mem_from_pool(ulong nquantas)
200 {
201     ulong total_req_size;
202 
203     mem_header_t* h;
204 
205     if (nquantas < 16)
206         nquantas = 16;
207 
208     total_req_size = nquantas * sizeof(mem_header_t);
209 
210     if (pool_free_pos + total_req_size <= 8 * 1024)
211     {
212         h = (mem_header_t*) (pool + pool_free_pos);
213         h->s.size = nquantas;
214         memmgr_free((void*) (h + 1));
215         pool_free_pos += total_req_size;
216     }
217     else
218     {
219         return 0;
220     }
221 
222     return freep;
223 }
224 
225 
226 
227 
228 
229 
230 
231 
232 
233 
memmgr_alloc(ulong nbytes)234 void* memmgr_alloc(ulong nbytes)
235 {
236     mem_header_t* p;
237     mem_header_t* prevp;
238 
239 
240 
241 
242 
243     ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;
244 
245 
246 
247 
248     if ((prevp = freep) == 0)
249     {
250         base.s.next = freep = prevp = &base;
251         base.s.size = 0;
252     }
253 
254     for (p = prevp->s.next; ; prevp = p, p = p->s.next)
255     {
256 
257         if (p->s.size >= nquantas)
258         {
259 
260             if (p->s.size == nquantas)
261             {
262 
263 
264 
265                 prevp->s.next = p->s.next;
266             }
267             else
268             {
269                 p->s.size -= nquantas;
270                 p += p->s.size;
271                 p->s.size = nquantas;
272             }
273 
274             freep = prevp;
275             return (void*) (p + 1);
276         }
277 
278 
279 
280 
281 
282 
283 
284         else if (p == freep)
285         {
286             if ((p = get_mem_from_pool(nquantas)) == 0)
287             {
288 
289 
290 
291                 return 0;
292             }
293         }
294     }
295 }
296 
297 
298 
299 
300 
301 
302 
memmgr_free(void * ap)303 void memmgr_free(void* ap)
304 {
305     mem_header_t* block;
306     mem_header_t* p;
307 
308 
309     block = ((mem_header_t*) ap) - 1;
310 
311 
312 
313 
314     for (p = freep; !(block > p && block < p->s.next); p = p->s.next)
315     {
316 
317 
318 
319 
320 
321         if (p >= p->s.next && (block > p || block < p->s.next))
322             break;
323     }
324 
325 
326 
327     if (block + block->s.size == p->s.next)
328     {
329         block->s.size += p->s.next->s.size;
330         block->s.next = p->s.next->s.next;
331     }
332     else
333     {
334         block->s.next = p->s.next;
335     }
336 
337 
338 
339     if (p + p->s.size == block)
340     {
341         p->s.size += block->s.size;
342         p->s.next = block->s.next;
343     }
344     else
345     {
346         p->s.next = block;
347     }
348 
349     freep = p;
350 }
351