00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "proj.h"
00034 #include "malloc.h"
00035
00036
00037
00038 struct _malloc_root_ malloc_root_
00039 =
00040 {
00041 {
00042 &malloc_root_.malloc_pool_image_,
00043 &malloc_root_.malloc_pool_image_,
00044 (mallocPool) &malloc_root_.malloc_pool_image_.eldest,
00045 (mallocPool) &malloc_root_.malloc_pool_image_.eldest,
00046 (mallocArea_) &malloc_root_.malloc_pool_image_.first,
00047 (mallocArea_) &malloc_root_.malloc_pool_image_.first,
00048 0,
00049 #if MALLOC_DEBUG
00050 0, 0, 0, 0, 0, 0, 0, { '/' }
00051 #else
00052 { 0 }
00053 #endif
00054 },
00055 };
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 static void *malloc_reserve_ = NULL;
00072 #if MALLOC_DEBUG
00073 static const char *const malloc_types_[] =
00074 {"KS", "KSR", "NF", "NFR", "US", "USR"};
00075 #endif
00076
00077
00078
00079 static void malloc_kill_area_ (mallocPool pool, mallocArea_ a);
00080 #if MALLOC_DEBUG
00081 static void malloc_verify_area_ (mallocPool pool, mallocArea_ a);
00082 #endif
00083
00084
00085
00086 #if MALLOC_DEBUG
00087 #define malloc_kill_(ptr,s) do {memset((ptr),127,(s));free((ptr));} while(0)
00088 #else
00089 #define malloc_kill_(ptr,s) free((ptr))
00090 #endif
00091
00092
00093
00094
00095
00096
00097
00098 static void
00099 malloc_kill_area_ (mallocPool pool UNUSED, mallocArea_ a)
00100 {
00101 #if MALLOC_DEBUG
00102 assert (strcmp (a->name, ((char *) (a->where)) + a->size) == 0);
00103 #endif
00104 malloc_kill_ (a->where, a->size);
00105 a->next->previous = a->previous;
00106 a->previous->next = a->next;
00107 #if MALLOC_DEBUG
00108 pool->freed += a->size;
00109 pool->frees++;
00110 #endif
00111 malloc_kill_ (a,
00112 offsetof (struct _malloc_area_, name)
00113 + strlen (a->name) + 1);
00114 }
00115
00116
00117
00118
00119
00120
00121
00122 #if MALLOC_DEBUG
00123 static void
00124 malloc_verify_area_ (mallocPool pool UNUSED, mallocArea_ a UNUSED)
00125 {
00126 mallocSize s = a->size;
00127
00128 assert (strcmp (a->name, ((char *) (a->where)) + s) == 0);
00129 }
00130 #endif
00131
00132
00133
00134
00135
00136
00137
00138 void
00139 malloc_init ()
00140 {
00141 if (malloc_reserve_ != NULL)
00142 return;
00143 malloc_reserve_ = xmalloc (20 * 1024);
00144 }
00145
00146
00147
00148
00149
00150
00151
00152
00153 void
00154 malloc_pool_display (mallocPool p UNUSED)
00155 {
00156 #if MALLOC_DEBUG
00157 mallocPool q;
00158 mallocArea_ a;
00159
00160 fprintf (dmpout, "Pool \"%s\": bytes allocated=%lu, freed=%lu, old sizes=%lu, new sizes\
00161 =%lu,\n allocations=%lu, frees=%lu, resizes=%lu, uses=%lu\n Subpools:\n",
00162 p->name, p->allocated, p->freed, p->old_sizes, p->new_sizes, p->allocations,
00163 p->frees, p->resizes, p->uses);
00164
00165 for (q = p->eldest; q != (mallocPool) & p->eldest; q = q->next)
00166 fprintf (dmpout, " \"%s\"\n", q->name);
00167
00168 fprintf (dmpout, " Storage areas:\n");
00169
00170 for (a = p->first; a != (mallocArea_) & p->first; a = a->next)
00171 {
00172 fprintf (dmpout, " ");
00173 malloc_display_ (a);
00174 }
00175 #endif
00176 }
00177
00178
00179
00180
00181
00182
00183
00184
00185 void
00186 malloc_pool_kill (mallocPool p)
00187 {
00188 mallocPool q;
00189 mallocArea_ a;
00190
00191 if (--p->uses != 0)
00192 return;
00193
00194 #if 0
00195 malloc_pool_display (p);
00196 #endif
00197
00198 assert (p->next->previous == p);
00199 assert (p->previous->next == p);
00200
00201
00202
00203 while ((q = p->eldest) != (mallocPool) &p->eldest)
00204 {
00205 q->uses = 1;
00206 malloc_pool_kill (q);
00207 }
00208
00209
00210
00211 while ((a = p->first) != (mallocArea_) & p->first)
00212 {
00213 malloc_kill_area_ (p, a);
00214 }
00215
00216
00217
00218 p->next->previous = p->previous;
00219 p->previous->next = p->next;
00220
00221
00222
00223 malloc_kill_ (p,
00224 offsetof (struct _malloc_pool_, name)
00225 + strlen (p->name) + 1);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235 mallocPool
00236 malloc_pool_new (const char *name, mallocPool parent,
00237 unsigned long chunks UNUSED)
00238 {
00239 mallocPool p;
00240
00241 if (parent == NULL)
00242 parent = malloc_pool_image ();
00243
00244 p = malloc_new_ (offsetof (struct _malloc_pool_, name)
00245 + (MALLOC_DEBUG ? strlen (name) + 1 : 0));
00246 p->next = (mallocPool) &(parent->eldest);
00247 p->previous = parent->youngest;
00248 parent->youngest->next = p;
00249 parent->youngest = p;
00250 p->eldest = (mallocPool) &(p->eldest);
00251 p->youngest = (mallocPool) &(p->eldest);
00252 p->first = (mallocArea_) &(p->first);
00253 p->last = (mallocArea_) &(p->first);
00254 p->uses = 1;
00255 #if MALLOC_DEBUG
00256 p->allocated = p->freed = p->old_sizes = p->new_sizes = p->allocations
00257 = p->frees = p->resizes = 0;
00258 strcpy (p->name, name);
00259 #endif
00260 return p;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 mallocPool
00272 malloc_pool_use (mallocPool pool)
00273 {
00274 ++pool->uses;
00275 return pool;
00276 }
00277
00278
00279
00280
00281
00282
00283
00284
00285 void
00286 malloc_display_ (mallocArea_ a UNUSED)
00287 {
00288 #if MALLOC_DEBUG
00289 fprintf (dmpout, "At %08lX, size=%" mallocSize_f "u, type=%s, \"%s\"\n",
00290 (unsigned long) a->where, a->size, malloc_types_[a->type], a->name);
00291 #endif
00292 }
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 mallocArea_
00304 malloc_find_inpool_ (mallocPool pool, void *ptr)
00305 {
00306 mallocArea_ a;
00307 mallocArea_ b = (mallocArea_) &pool->first;
00308 int n = 0;
00309
00310 for (a = pool->first; a != (mallocArea_) &pool->first; a = a->next)
00311 {
00312 assert (("Infinite loop detected" != NULL) && (a != b));
00313 if (a->where == ptr)
00314 return a;
00315 ++n;
00316 if (n & 1)
00317 b = b->next;
00318 }
00319 assert ("Couldn't find object in pool!" == NULL);
00320 return NULL;
00321 }
00322
00323
00324
00325
00326
00327
00328
00329
00330 void
00331 malloc_kill_inpool_ (mallocPool pool, mallocType_ type UNUSED,
00332 void *ptr, mallocSize s UNUSED)
00333 {
00334 mallocArea_ a;
00335
00336 if (pool == NULL)
00337 pool = malloc_pool_image ();
00338
00339 #if MALLOC_DEBUG
00340 assert ((pool == malloc_pool_image ())
00341 || malloc_pool_find_ (pool, malloc_pool_image ()));
00342 #endif
00343
00344 a = malloc_find_inpool_ (pool, ptr);
00345 #if MALLOC_DEBUG
00346 assert (a->type == type);
00347 if ((type != MALLOC_typeUS_) && (type != MALLOC_typeUSR_))
00348 assert (a->size == s);
00349 #endif
00350 malloc_kill_area_ (pool, a);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359 void *
00360 malloc_new_ (mallocSize s)
00361 {
00362 void *ptr;
00363 unsigned ss = s;
00364
00365 #if MALLOC_DEBUG && 0
00366 assert (s == (mallocSize) ss);
00367
00368 #endif
00369
00370 ptr = xmalloc (ss);
00371 #if MALLOC_DEBUG
00372 memset (ptr, 126, ss);
00373
00374 #endif
00375 return ptr;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385 void *
00386 malloc_new_inpool_ (mallocPool pool, mallocType_ type, const char *name, mallocSize s)
00387 {
00388 void *ptr;
00389 mallocArea_ a;
00390 unsigned short i;
00391
00392 if (pool == NULL)
00393 pool = malloc_pool_image ();
00394
00395 #if MALLOC_DEBUG
00396 assert ((pool == malloc_pool_image ())
00397 || malloc_pool_find_ (pool, malloc_pool_image ()));
00398 #endif
00399
00400 ptr = malloc_new_ (s + (i = (MALLOC_DEBUG ? strlen (name) + 1 : 0)));
00401 #if MALLOC_DEBUG
00402 strcpy (((char *) (ptr)) + s, name);
00403 #endif
00404 a = malloc_new_ (offsetof (struct _malloc_area_, name) + i);
00405 switch (type)
00406 {
00407
00408 case MALLOC_typeKP_:
00409 case MALLOC_typeKPR_:
00410 a->next = (mallocArea_) &pool->first;
00411 break;
00412
00413 default:
00414 a->next = pool->first;
00415 break;
00416 }
00417 a->previous = a->next->previous;
00418 a->next->previous = a;
00419 a->previous->next = a;
00420 a->where = ptr;
00421 #if MALLOC_DEBUG
00422 a->size = s;
00423 a->type = type;
00424 strcpy (a->name, name);
00425 pool->allocated += s;
00426 pool->allocations++;
00427 #endif
00428 return ptr;
00429 }
00430
00431
00432
00433
00434
00435
00436
00437
00438 void *
00439 malloc_new_zinpool_ (mallocPool pool, mallocType_ type, const char *name, mallocSize s,
00440 int z)
00441 {
00442 void *ptr;
00443
00444 ptr = malloc_new_inpool_ (pool, type, name, s);
00445 memset (ptr, z, s);
00446 return ptr;
00447 }
00448
00449
00450
00451
00452
00453
00454
00455
00456 char
00457 malloc_pool_find_ (mallocPool pool, mallocPool parent)
00458 {
00459 mallocPool p;
00460
00461 for (p = parent->eldest; p != (mallocPool) & parent->eldest; p = p->next)
00462 {
00463 if ((p == pool) || malloc_pool_find_ (pool, p))
00464 return 1;
00465 }
00466 return 0;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475 void *
00476 malloc_resize_inpool_ (mallocPool pool, mallocType_ type UNUSED,
00477 void *ptr, mallocSize ns, mallocSize os UNUSED)
00478 {
00479 mallocArea_ a;
00480
00481 if (pool == NULL)
00482 pool = malloc_pool_image ();
00483
00484 #if MALLOC_DEBUG
00485 assert ((pool == malloc_pool_image ())
00486 || malloc_pool_find_ (pool, malloc_pool_image ()));
00487 #endif
00488
00489 a = malloc_find_inpool_ (pool, ptr);
00490 #if MALLOC_DEBUG
00491 assert (a->type == type);
00492 if ((type == MALLOC_typeKSR_) || (type == MALLOC_typeKPR_))
00493 assert (a->size == os);
00494 assert (strcmp (a->name, ((char *) (ptr)) + os) == 0);
00495 #endif
00496 ptr = malloc_resize_ (ptr, ns + (MALLOC_DEBUG ? strlen (a->name) + 1: 0));
00497 a->where = ptr;
00498 #if MALLOC_DEBUG
00499 a->size = ns;
00500 strcpy (((char *) (ptr)) + ns, a->name);
00501 pool->old_sizes += os;
00502 pool->new_sizes += ns;
00503 pool->resizes++;
00504 #endif
00505 return ptr;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514 void *
00515 malloc_resize_ (void *ptr, mallocSize s)
00516 {
00517 int ss = s;
00518
00519 #if MALLOC_DEBUG && 0
00520 assert (s == (mallocSize) ss);
00521 #endif
00522
00523 ptr = xrealloc (ptr, ss);
00524 return ptr;
00525 }
00526
00527
00528
00529
00530
00531
00532 void
00533 malloc_verify_inpool_ (mallocPool pool UNUSED, mallocType_ type UNUSED,
00534 void *ptr UNUSED, mallocSize s UNUSED)
00535 {
00536 #if MALLOC_DEBUG
00537 mallocArea_ a;
00538
00539 if (pool == NULL)
00540 pool = malloc_pool_image ();
00541
00542 assert ((pool == malloc_pool_image ())
00543 || malloc_pool_find_ (pool, malloc_pool_image ()));
00544
00545 a = malloc_find_inpool_ (pool, ptr);
00546 assert (a->type == type);
00547 if ((type != MALLOC_typeUS_) && (type != MALLOC_typeUSR_))
00548 assert (a->size == s);
00549 malloc_verify_area_ (pool, a);
00550 #endif
00551 }