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()144void 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()153void 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)199static 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)234void* 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)303void 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