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
00034
00035
00036
00037 #include <sys/types.h>
00038 #include <malloc.h>
00039 #include <string.h>
00040
00041 #include "defs.h"
00042 #include "mempool.h"
00043 #include "tracing.h"
00044 #include "erglob.h"
00045
00046
00047
00048
00049
00050 #define MEM_POOL_INIT_IN_PROGRESS (-1)
00051
00052
00053
00054
00055
00056
00057 #define BLOCK_SIZE 0x2000
00058
00059
00060
00061
00062 #define MIN_LARGE_BLOCK_SIZE 0x800
00063
00064
00065
00066 #ifdef Is_True_On
00067 #define ZAP_ON_FREE (1)
00068 #endif
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 MEM_POOL MEM_local_pool;
00079 MEM_POOL MEM_src_pool;
00080 MEM_POOL MEM_pu_pool;
00081 MEM_POOL MEM_phase_pool;
00082
00083 MEM_POOL *MEM_local_pool_ptr = &MEM_local_pool;
00084 MEM_POOL *MEM_src_pool_ptr = &MEM_src_pool;
00085 MEM_POOL *MEM_pu_pool_ptr = &MEM_pu_pool;
00086 MEM_POOL *MEM_phase_pool_ptr = &MEM_phase_pool;
00087
00088
00089
00090
00091
00092 MEM_POOL MEM_local_nz_pool;
00093 MEM_POOL MEM_src_nz_pool;
00094 MEM_POOL MEM_pu_nz_pool;
00095 MEM_POOL MEM_phase_nz_pool;
00096
00097 MEM_POOL *MEM_local_nz_pool_ptr = &MEM_local_nz_pool;
00098 MEM_POOL *MEM_src_nz_pool_ptr = &MEM_src_nz_pool;
00099 MEM_POOL *MEM_pu_nz_pool_ptr = &MEM_pu_nz_pool;
00100 MEM_POOL *MEM_phase_nz_pool_ptr = &MEM_phase_nz_pool;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 struct mem_block {
00113 size_t avail;
00114
00115
00116 MEM_PTR ptr;
00117
00118 MEM_BLOCK *rest;
00119
00120
00121 };
00122
00123 #define MEM_BLOCK_avail(x) ((x)->avail)
00124 #define MEM_BLOCK_ptr(x) ((x)->ptr)
00125 #define MEM_BLOCK_rest(x) ((x)->rest)
00126
00127 #define MEM_BLOCK_first_ptr(x) \
00128 (MEM_PTR) (((char *) (x)) + PAD_TO_ALIGN(sizeof(MEM_BLOCK)))
00129
00130
00131
00132
00133
00134
00135 typedef struct mem_large_block MEM_LARGE_BLOCK;
00136 struct mem_large_block {
00137 MEM_LARGE_BLOCK *next;
00138 MEM_LARGE_BLOCK *prev;
00139 MEM_POOL_BLOCKS *base;
00140 MEM_PTR ptr;
00141 };
00142
00143 #define MEM_LARGE_BLOCK_next(x) ((x)->next)
00144 #define MEM_LARGE_BLOCK_prev(x) ((x)->prev)
00145 #define MEM_LARGE_BLOCK_base(x) ((x)->base)
00146 #define MEM_LARGE_BLOCK_ptr(x) ((x)->ptr)
00147 #define MEM_LARGE_BLOCK_OVERHEAD (PAD_TO_ALIGN(sizeof(MEM_LARGE_BLOCK)))
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160 static void
00161 MEM_LARGE_BLOCK_zap(MEM_LARGE_BLOCK *block)
00162 {
00163 MEM_LARGE_BLOCK_base(block) = NULL;
00164 MEM_LARGE_BLOCK_ptr(block) = NULL;
00165 }
00166
00167 static void
00168 MEM_LARGE_BLOCK_free(MEM_LARGE_BLOCK *block)
00169 {
00170 MEM_LARGE_BLOCK_zap(block);
00171 free(block);
00172 }
00173
00174 static MEM_LARGE_BLOCK *
00175 MEM_LARGE_BLOCK_realloc(MEM_LARGE_BLOCK *old_block, INT64 new_size)
00176 {
00177 MEM_POOL_BLOCKS * const base = MEM_LARGE_BLOCK_base(old_block);
00178 MEM_PTR const ptr = MEM_LARGE_BLOCK_ptr(old_block);
00179 MEM_LARGE_BLOCK * new_block;
00180
00181 MEM_LARGE_BLOCK_zap(old_block);
00182 new_block = (MEM_LARGE_BLOCK *)realloc(old_block, new_size);
00183 if (new_block != NULL)
00184 {
00185 MEM_LARGE_BLOCK_base(new_block) = base;
00186 MEM_LARGE_BLOCK_ptr(new_block) = ptr;
00187 }
00188 return new_block;
00189 }
00190
00191
00192
00193
00194
00195 typedef struct int_list INT_LIST;
00196
00197 struct int_list {
00198 INT32 first;
00199
00200 INT_LIST *rest;
00201
00202 };
00203
00204 #define INT_LIST_first(x) ((x)->first)
00205 #define INT_LIST_rest(x) ((x)->rest)
00206
00207 static INT_LIST *free_int_lists;
00208
00209
00210
00211
00212
00213
00214 struct mem_stat {
00215 const char *file;
00216
00217 INT32 line;
00218
00219 INT32 total;
00220
00221
00222 INT32 current;
00223
00224
00225 INT32 max_t;
00226
00227
00228
00229 size_t max_s;
00230
00231
00232
00233 INT32 last;
00234
00235
00236 INT32 last_grew;
00237
00238
00239
00240 INT32 last_shrank;
00241
00242
00243
00244 INT32 count;
00245
00246 MEM_STAT *hash_list_rest;
00247
00248
00249 MEM_STAT *pool_list_rest;
00250
00251
00252 INT_LIST *saved_current;
00253
00254
00255
00256 MEM_POOL *pool;
00257
00258 };
00259
00260 #define MEM_STAT_file(x) ((x)->file)
00261 #define MEM_STAT_line(x) ((x)->line)
00262 #define MEM_STAT_total(x) ((x)->total)
00263 #define MEM_STAT_current(x) ((x)->current)
00264 #define MEM_STAT_max_t(x) ((x)->max_t)
00265 #define MEM_STAT_max_s(x) ((x)->max_s)
00266 #define MEM_STAT_last(x) ((x)->last)
00267 #define MEM_STAT_last_grew(x) ((x)->last_grew)
00268 #define MEM_STAT_last_shrank(x) ((x)->last_shrank)
00269 #define MEM_STAT_count(x) ((x)->count)
00270 #define MEM_STAT_hash_list_rest(x) ((x)->hash_list_rest)
00271 #define MEM_STAT_pool_list_rest(x) ((x)->pool_list_rest)
00272 #define MEM_STAT_saved_current(x) ((x)->saved_current)
00273 #define MEM_STAT_pool(x) ((x)->pool)
00274
00275
00276
00277
00278
00279
00280
00281 struct mem_pool_blocks {
00282 MEM_BLOCK *block;
00283
00284 MEM_LARGE_BLOCK *large_block;
00285
00286 MEM_BLOCK *base_block;
00287
00288
00289 MEM_PTR *base_ptr;
00290
00291 size_t base_avail;
00292
00293
00294 MEM_POOL_BLOCKS *rest;
00295
00296
00297
00298
00299 };
00300
00301 #define MEM_POOL_BLOCKS_block(x) ((x)->block)
00302 #define MEM_POOL_BLOCKS_large_block(x) ((x)->large_block)
00303 #define MEM_POOL_BLOCKS_base_block(x) ((x)->base_block)
00304 #define MEM_POOL_BLOCKS_base_ptr(x) ((x)->base_ptr)
00305 #define MEM_POOL_BLOCKS_base_avail(x) ((x)->base_avail)
00306 #define MEM_POOL_BLOCKS_rest(x) ((x)->rest)
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 struct mem_pure_stack {
00351 MEM_PTR last_alloc;
00352 MEM_PURE_STACK *prev_stack;
00353
00354
00355 };
00356
00357 #define MEM_PURE_STACK_last_alloc(x) ((x)->last_alloc)
00358 #define MEM_PURE_STACK_prev_stack(x) ((x)->prev_stack)
00359 #define MEM_POOL_last_alloc(x) \
00360 MEM_PURE_STACK_last_alloc(MEM_POOL_pure_stack(x))
00361 #define MEM_POOL_prev_stack(x) \
00362 MEM_PURE_STACK_prev_stack(MEM_POOL_pure_stack(x))
00363 BOOL purify_pools = FALSE;
00364 static BOOL purify_pools_trace = FALSE;
00365 static BOOL purify_pools_trace_x = FALSE;
00366
00367 #define MAGIC_NUM 0xabcd
00368
00369
00370
00371
00372 #define MEM_POOL_name(x) ((x)->name)
00373 #define MEM_POOL_blocks(x) ((x)->blocks)
00374 #define MEM_POOL_bz(x) ((x)->bz)
00375 #define MEM_POOL_rest(x) ((x)->rest)
00376 #define MEM_POOL_pure_stack(x) ((x)->pure_stack)
00377 #define MEM_POOL_frozen(x) ((x)->frozen)
00378 #define MEM_POOL_magic_num(x) ((x)->magic_num)
00379 #define MEM_POOL_alloc_site_list(x) ((x)->alloc_site_list)
00380
00381 #define MEM_POOL_block(x) \
00382 MEM_POOL_BLOCKS_block(MEM_POOL_blocks(x))
00383 #define MEM_POOL_large_block(x) \
00384 MEM_POOL_BLOCKS_large_block(MEM_POOL_blocks(x))
00385
00386
00387
00388
00389
00390 static MEM_POOL_BLOCKS *free_mem_pool_blocks_list;
00391
00392
00393
00394 static MEM_POOL_BLOCKS overhead_blocks;
00395
00396
00397
00398 static MEM_POOL mem_overhead_pool =
00399
00400
00401 {
00402 "memory overhead",
00403 &overhead_blocks,
00404 NULL,
00405 NULL,
00406 TRUE,
00407 FALSE,
00408 MAGIC_NUM,
00409 NULL
00410 };
00411
00412 static MEM_POOL *The_Default_Mem_Pool;
00413
00414
00415
00416 #define PAD_TO_ALIGN(size) (((size) + 7) & (~0U << 3))
00417
00418
00419
00420
00421 static BOOL mem_tracing_enabled = FALSE;
00422 #ifdef Is_True_On
00423 static MEM_POOL *initialized_pools =
00424
00425
00426 &mem_overhead_pool;
00427 #endif
00428
00429 #define N_BUCKETS 503
00430
00431 static MEM_STAT *call_site_hash_tab[N_BUCKETS];
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446 static UINT32
00447 Hash(
00448 INT32 line,
00449 const char *file
00450 )
00451 {
00452 const char *p;
00453 UINT32 result = line;
00454
00455
00456
00457
00458 for ( p = file; *p; ++p )
00459 result = ((result << 1) ^ (result >> 1) ^ *p) + *p;
00460
00461 return result % N_BUCKETS;
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 static MEM_STAT*
00479 Hash_Get(
00480 UINT32 hn,
00481 MEM_POOL *pool,
00482 INT32 line,
00483 const char *file
00484 )
00485 {
00486 MEM_STAT *as;
00487
00488 for ( as = call_site_hash_tab[hn];
00489 as != NULL;
00490 as = MEM_STAT_hash_list_rest(as)
00491 ) {
00492 if ( MEM_STAT_line(as) == line
00493 && strcmp(MEM_STAT_file(as),file) == 0
00494 && MEM_STAT_pool(as) == pool
00495 ) {
00496 return as;
00497 }
00498 }
00499
00500 return NULL;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 static void
00519 Site_Account_Alloc(
00520 MEM_POOL *pool,
00521 size_t old_size,
00522 size_t new_size
00523 MEM_STAT_ARGS(line,file)
00524 )
00525 {
00526 INT32 size = new_size - old_size;
00527 UINT32 hn = Hash(line,file);
00528 MEM_STAT *ms = Hash_Get(hn,pool,line,file);
00529
00530 if ( ms == NULL ) {
00531 ms = (MEM_STAT *) calloc(1,sizeof(MEM_STAT));
00532
00533 MEM_STAT_pool(ms) = pool;
00534 MEM_STAT_line(ms) = line;
00535 MEM_STAT_file(ms) = file;
00536 MEM_STAT_hash_list_rest(ms) = call_site_hash_tab[hn];
00537 call_site_hash_tab[hn] = ms;
00538 MEM_STAT_pool_list_rest(ms) = MEM_POOL_alloc_site_list(pool);
00539 MEM_POOL_alloc_site_list(pool) = ms;
00540 }
00541
00542 MEM_STAT_current(ms) += size;
00543 MEM_STAT_total(ms) += size;
00544 if ( size > MEM_STAT_last(ms) )
00545 ++MEM_STAT_last_grew(ms);
00546 else if ( size < MEM_STAT_last(ms) )
00547 ++MEM_STAT_last_shrank(ms);
00548 MEM_STAT_max_t(ms) = Max(MEM_STAT_max_t(ms),MEM_STAT_current(ms));
00549 MEM_STAT_max_s(ms) = Max(MEM_STAT_max_s(ms),size);
00550 MEM_STAT_last(ms) = size;
00551 ++MEM_STAT_count(ms);
00552 }
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 static void
00568 Site_Account_Pop(
00569 MEM_POOL *pool
00570 MEM_STAT_ARGS(line,file)
00571 )
00572 {
00573 MEM_STAT *ms;
00574
00575 for ( ms = MEM_POOL_alloc_site_list(pool);
00576 ms != NULL;
00577 ms = MEM_STAT_pool_list_rest(ms)
00578 ) {
00579 INT_LIST *tmp = MEM_STAT_saved_current(ms);
00580
00581 if ( tmp == NULL ) {
00582
00583
00584
00585 MEM_STAT_current(ms) = 0;
00586 }
00587 else {
00588 MEM_STAT_current(ms) = INT_LIST_first(tmp);
00589 MEM_STAT_saved_current(ms) = INT_LIST_rest(tmp);
00590 INT_LIST_rest(tmp) = free_int_lists;
00591 free_int_lists = tmp;
00592 }
00593 }
00594 }
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607 static void
00608 Site_Account_Push(
00609 MEM_POOL *pool
00610 MEM_STAT_ARGS(line,file)
00611 )
00612 {
00613 MEM_STAT *ms;
00614
00615 for ( ms = MEM_POOL_alloc_site_list(pool);
00616 ms != NULL;
00617 ms = MEM_STAT_pool_list_rest(ms)
00618 ) {
00619 INT_LIST *il;
00620
00621 if ( free_int_lists == NULL )
00622 il = TYPE_MEM_POOL_ALLOC(INT_LIST,&mem_overhead_pool);
00623 else {
00624 il = free_int_lists;
00625
00626 free_int_lists = INT_LIST_rest(il);
00627 }
00628
00629 INT_LIST_rest(il) = MEM_STAT_saved_current(ms);
00630 MEM_STAT_saved_current(ms) = il;
00631 INT_LIST_first(il) = MEM_STAT_current(ms);
00632 }
00633 }
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 static INT32
00645 Field_Size(
00646 INT32 i
00647 )
00648 {
00649 char buff[100];
00650
00651
00652
00653
00654 sprintf(buff,"%d",i);
00655 return strlen(buff);
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 typedef INT (*QSORT_FUNC) (const void *, const void *);
00672
00673 static INT
00674 MEM_STAT_Sort(
00675 MEM_STAT **as1p,
00676 MEM_STAT **as2p
00677 )
00678 {
00679 MEM_STAT *as1 = *as1p;
00680 MEM_STAT *as2 = *as2p;
00681
00682 return MEM_STAT_max_t(as2) - MEM_STAT_max_t(as1);
00683 }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 static BOOL
00695 MEM_STAT_In_List(
00696 MEM_POOL *list,
00697 MEM_POOL *pool
00698 )
00699 {
00700 for ( ;
00701 list != NULL;
00702 list = MEM_POOL_rest(list)
00703 ) {
00704 if ( list == pool )
00705 return ( TRUE );
00706 }
00707
00708 return ( FALSE );
00709 }
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 INT32
00724 MEM_POOL_Report(
00725 MEM_POOL *pool,
00726 INT32 used_total
00727 )
00728 {
00729 MEM_STAT *as;
00730 MEM_STAT **as_vec;
00731 INT32 i;
00732 INT32 total_current = 0;
00733 INT32 total_allocated = 0;
00734 INT32 max_allocated = 0;
00735 INT32 current_fs = 3;
00736 INT32 total_fs = 3;
00737 INT32 max_t_fs = 4;
00738 INT32 max_s_fs = 4;
00739 INT32 count_fs = 5;
00740 INT32 last_grew_fs = 4;
00741 INT32 last_shrank_fs = 6;
00742 INT32 site_count = 0;
00743
00744 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
00745 ("Report from un-initialized MEM_POOL %s\n", MEM_POOL_name(pool)));
00746
00747 fprintf(TFile,"----- %s callsites\n",MEM_POOL_name(pool));
00748
00749
00750
00751 for ( as = MEM_POOL_alloc_site_list(pool);
00752 as != NULL;
00753 as = MEM_STAT_pool_list_rest(as)
00754 ) {
00755 current_fs = Max(current_fs,Field_Size(MEM_STAT_current(as)));
00756 total_fs = Max(total_fs,Field_Size(MEM_STAT_total(as)));
00757 max_t_fs = Max(max_t_fs,Field_Size(MEM_STAT_max_t(as)));
00758 max_s_fs = Max(max_s_fs,Field_Size(MEM_STAT_max_s(as)));
00759 count_fs = Max(count_fs,Field_Size(MEM_STAT_count(as)));
00760 last_grew_fs = Max(last_grew_fs,
00761 Field_Size(MEM_STAT_last_grew(as)));
00762 last_shrank_fs = Max(last_shrank_fs,
00763 Field_Size(MEM_STAT_last_shrank(as)));
00764
00765 ++site_count;
00766 }
00767
00768
00769
00770 MEM_POOL_Push(&mem_overhead_pool);
00771 as_vec = TYPE_MEM_POOL_ALLOC_N(MEM_STAT *,&mem_overhead_pool,
00772 site_count);
00773
00774 for ( as = MEM_POOL_alloc_site_list(pool), i = 0;
00775 as != NULL;
00776 as = MEM_STAT_pool_list_rest(as), ++i
00777 ) {
00778 as_vec[i] = as;
00779 }
00780
00781 qsort((void*)as_vec,site_count,
00782 sizeof(MEM_STAT*),
00783 (QSORT_FUNC) MEM_STAT_Sort);
00784
00785
00786
00787 fprintf(TFile,"%*s %*s %*s %*s %*s %*s %*s Site\n",
00788 max_t_fs,
00789 "maxt",
00790 current_fs,
00791 "cur",
00792 total_fs,
00793 "tot",
00794 max_s_fs,
00795 "maxs",
00796 count_fs,
00797 "count",
00798 last_grew_fs,
00799 "grew",
00800 last_shrank_fs,
00801 "shrank");
00802
00803
00804
00805 for ( i = 0; i < site_count; ++i ) {
00806 as = as_vec[i];
00807
00808 fprintf(TFile,"%*d %*d %*d %*d %*d %*d %*d %s %d\n",
00809 max_t_fs,
00810 MEM_STAT_max_t(as),
00811 current_fs,
00812 MEM_STAT_current(as),
00813 total_fs,
00814 MEM_STAT_total(as),
00815 max_s_fs,
00816 MEM_STAT_max_s(as),
00817 count_fs,
00818 MEM_STAT_count(as),
00819 last_grew_fs,
00820 MEM_STAT_last_grew(as),
00821 last_shrank_fs,
00822 MEM_STAT_last_shrank(as),
00823 MEM_STAT_file(as),
00824 MEM_STAT_line(as));
00825 total_current += MEM_STAT_current(as);
00826 total_allocated += MEM_STAT_total(as);
00827 max_allocated += MEM_STAT_max_t(as);
00828 }
00829
00830 MEM_POOL_Pop(&mem_overhead_pool);
00831
00832 fprintf(TFile,"++++ Allocated for %s pool: total=%d, max=%d, current=%d (%d%%used)\n",
00833 MEM_POOL_name(pool),
00834 total_allocated,
00835 max_allocated,
00836 total_current,
00837 (INT) (100.0 * ( ((double) total_current)
00838 / ((double) used_total))));
00839 return total_allocated;
00840 }
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 void
00852 MEM_Trace(void)
00853 {
00854 #ifdef Is_True_On
00855
00856 #if defined(linux) || defined(MEM_STATS)
00857 MEM_POOL *pool;
00858 struct mallinfo mi = mallinfo();
00859 INT32 used_total = mi.usmblks + mi.uordblks;
00860 INT32 total_allocated = 0;
00861
00862 fprintf(TFile,"arena %10d\n",mi.arena);
00863 fprintf(TFile,"ordblks %10d\n",mi.ordblks);
00864 fprintf(TFile,"smblks %10d\n",mi.smblks);
00865 fprintf(TFile,"hblkhd %10d\n",mi.hblkhd);
00866 fprintf(TFile,"hblks %10d\n",mi.hblks);
00867 fprintf(TFile,"usmblks %10d\n",mi.usmblks);
00868 fprintf(TFile,"fsmblks %10d\n",mi.fsmblks);
00869 fprintf(TFile,"uordblks %10d\n",mi.uordblks);
00870 fprintf(TFile,"fordblks %10d\n",mi.fordblks);
00871 fprintf(TFile,"keepcost %10d\n",mi.keepcost);
00872
00873 for ( pool = initialized_pools;
00874 pool != NULL;
00875 pool = MEM_POOL_rest(pool)
00876 ) {
00877 total_allocated += MEM_POOL_Report(pool,used_total);
00878 }
00879 fprintf(TFile,"++++ Total Allocated = %d\n",total_allocated);
00880 #else
00881 fprintf(TFile,
00882 "MEM_Trace: Not available; compiler not compiled with MEM_STATS\n");
00883 #endif
00884 #else
00885 fprintf(TFile,
00886 "MEM_Trace: Not available; compiler not compiled with Is_True_On\n");
00887 #endif
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 void
00900 Trace_Memory_Allocation (
00901 const INT phase,
00902 const char *const pname )
00903 {
00904 if ( Get_Trace ( TKIND_ALLOC, phase ) ) {
00905 fprintf ( TFile,
00906 "\n%s%s\tMemory allocation information after %s\n%s%s\n",
00907 DBar, DBar, pname, DBar, DBar );
00908 MEM_Trace ();
00909 }
00910 }
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 void
00922 MEM_Tracing_Enable(void)
00923 {
00924 #ifdef Is_True_On
00925 mem_tracing_enabled = TRUE;
00926 #endif
00927 }
00928
00929
00930
00931 #if Is_True_On
00932 const char *special_address = NULL;
00933 const char *special_address_owner = "NOBODY";
00934 #endif
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947 static MEM_PTR
00948 Allocate_Block (MEM_POOL *pool)
00949 {
00950 MEM_BLOCK *block = (MEM_BLOCK *)
00951 malloc (BLOCK_SIZE + PAD_TO_ALIGN(sizeof(MEM_BLOCK)));
00952
00953 if (block == NULL)
00954 ErrMsg (EC_No_Mem, "Allocate_Block");
00955
00956 if ( MEM_POOL_bz(pool) )
00957 memset (block, '\0', BLOCK_SIZE + PAD_TO_ALIGN(sizeof(MEM_BLOCK)));
00958
00959 #ifdef ZAP_ON_FREE
00960 else
00961 memset(((char *) block), 0xa5,
00962 BLOCK_SIZE + PAD_TO_ALIGN(sizeof(MEM_BLOCK)));
00963 #endif
00964
00965 MEM_BLOCK_avail(block) = BLOCK_SIZE;
00966 MEM_BLOCK_ptr(block) = MEM_BLOCK_first_ptr(block);
00967 MEM_BLOCK_rest(block) = MEM_POOL_block(pool);
00968 MEM_POOL_block(pool) = block;
00969
00970 #if Is_True_On
00971 if (special_address >= ((char *) MEM_BLOCK_ptr(block)) &&
00972 special_address < (((char *) MEM_BLOCK_ptr(block)) +
00973 MEM_BLOCK_avail(block))) {
00974 fprintf(TFile, "Pool %s given %llu bytes from 0x%p to 0x%p\n",
00975 MEM_POOL_name(pool), (UINT64)MEM_BLOCK_avail(block),
00976 (char *) MEM_BLOCK_ptr(block),
00977 ((char *) MEM_BLOCK_ptr(block)) + MEM_BLOCK_avail(block));
00978 special_address_owner = MEM_POOL_name(pool);
00979 }
00980 #endif
00981
00982 return block;
00983 }
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 static MEM_PTR
00998 Allocate_Large_Block (MEM_POOL *pool, INT32 size)
00999 {
01000 MEM_LARGE_BLOCK *block;
01001 size += MEM_LARGE_BLOCK_OVERHEAD;
01002 block = (MEM_LARGE_BLOCK *) malloc (size);
01003
01004 if (block == NULL)
01005 ErrMsg (EC_No_Mem, "Allocate_Large_Block");
01006
01007 if ( MEM_POOL_bz(pool) ) {
01008 memset (block, '\0', size);
01009 }
01010
01011 #ifdef ZAP_ON_FREE
01012 else
01013 memset(((char *) block), 0xa5, size);
01014 #endif
01015
01016 MEM_LARGE_BLOCK_ptr(block) = (MEM_PTR)
01017 (((char *)block) + MEM_LARGE_BLOCK_OVERHEAD);
01018 MEM_LARGE_BLOCK_base(block) = MEM_POOL_blocks(pool);
01019 MEM_LARGE_BLOCK_next(block) = MEM_POOL_large_block(pool);
01020 MEM_LARGE_BLOCK_prev(block) = NULL;
01021 if (MEM_LARGE_BLOCK_next(block) != NULL)
01022 MEM_LARGE_BLOCK_prev(MEM_LARGE_BLOCK_next(block)) = block;
01023 MEM_POOL_large_block(pool) = block;
01024
01025 return MEM_LARGE_BLOCK_ptr(block);
01026 }
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042 static MEM_PTR
01043 Raw_Allocate(
01044 MEM_POOL *pool,
01045 INT32 size
01046 )
01047 {
01048 MEM_PTR *result;
01049
01050 if (size <= MIN_LARGE_BLOCK_SIZE) {
01051 MEM_BLOCK *b;
01052 b = MEM_POOL_block(pool);
01053
01054 if (b == NULL || MEM_BLOCK_avail(b) < size) {
01055 b = Allocate_Block (pool);
01056 }
01057
01058 result = MEM_BLOCK_ptr(b);
01059 MEM_BLOCK_ptr(b) = (MEM_PTR) (((char*) MEM_BLOCK_ptr(b)) + size);
01060 MEM_BLOCK_avail(b) -= size;
01061
01062 return result;
01063 } else
01064
01065 return Allocate_Large_Block (pool, size);
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080 MEM_PTR
01081 MEM_POOL_Alloc_P
01082 (
01083 MEM_POOL *pool,
01084 size_t size
01085 MEM_STAT_ARGS(line,file)
01086 )
01087 {
01088 if (pool == Default_Mem_Pool) pool = The_Default_Mem_Pool;
01089 if (pool == Malloc_Mem_Pool) {
01090 MEM_PTR p = malloc(size);
01091 if (p == NULL)
01092 ErrMsg (EC_No_Mem, "MEM_POOL_Alloc");
01093 return p;
01094 }
01095
01096 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01097 ("Alloc from un-initialized MEM_POOL %s\n", MEM_POOL_name(pool)));
01098
01099 #ifdef JUST_USE_MALLOC
01100 return calloc(1,size);
01101 #endif
01102
01103 if (purify_pools) {
01104 MEM_PTR ret_val;
01105
01106
01107 if (!MEM_POOL_blocks(pool)) {
01108 DevWarn("Allocation from %s before MEM_POOL_Push(%s)",
01109 MEM_POOL_name(pool), MEM_POOL_name(pool));
01110 MEM_POOL_blocks(pool) = (MEM_POOL_BLOCKS *) TRUE;
01111 }
01112
01113 ret_val = calloc(1,size+8);
01114 Is_True (ret_val, ("MEM_POOL_Alloc: calloc returned NULL"));
01115 Is_True (MEM_POOL_pure_stack(pool), ("MEM_POOL_Alloc %s: missing stack",
01116 MEM_POOL_name(pool)));
01117 *(MEM_PTR*)ret_val = MEM_POOL_last_alloc(pool);
01118 MEM_POOL_last_alloc(pool) = ret_val;
01119 if (purify_pools_trace)
01120 printf ("pool %s, alloc 0x%p, size %llu, (0x%p - 0x%p)\n",
01121 MEM_POOL_name(pool), (char *)ret_val+8, (UINT64)size,
01122 (char *)ret_val+8, (char *)ret_val+size);
01123 return ((MEM_PTR) ((size_t)ret_val+8));
01124 }
01125
01126 Is_True(MEM_POOL_blocks(pool) != NULL,
01127 ("Alloc with uninitialized MEM_POOL"));
01128 #ifdef Is_True_On
01129 if ( mem_tracing_enabled )
01130 Site_Account_Alloc(pool,0,size,line,file);
01131 #endif
01132
01133
01134
01135 size = PAD_TO_ALIGN(size);
01136
01137 return Raw_Allocate(pool,size);
01138
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 MEM_PTR
01152 MEM_POOL_Realloc_P
01153 (
01154 MEM_POOL *pool,
01155 MEM_PTR old_block,
01156 size_t old_size,
01157 size_t new_size
01158 MEM_STAT_ARGS(line,file)
01159 )
01160 {
01161 MEM_PTR result;
01162
01163 if (pool == Default_Mem_Pool) pool = The_Default_Mem_Pool;
01164 if (pool == Malloc_Mem_Pool) {
01165 MEM_PTR p = realloc(old_block,new_size);
01166 if (p == NULL)
01167 ErrMsg (EC_No_Mem, "MEM_POOL_Realloc");
01168 return p;
01169 }
01170
01171 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01172 ("Realloc from un-initialized MEM_POOL %s\n", MEM_POOL_name(pool)));
01173
01174 #ifdef JUST_USE_MALLOC
01175 result = realloc(old_block,new_size);
01176 if ( old_size < new_size )
01177 memset((char*)result + old_size, '\0', new_size - old_size);
01178 return result;
01179 #endif
01180
01181 if (purify_pools) {
01182 MEM_PTR ret_val = NULL;
01183 BOOL foundit = FALSE;
01184
01185 if (!MEM_POOL_blocks(pool)) {
01186 DevWarn("Realloc from %s before MEM_POOL_Push(%s)",
01187 MEM_POOL_name(pool), MEM_POOL_name(pool));
01188 MEM_POOL_blocks(pool) = (MEM_POOL_BLOCKS *) TRUE;
01189 }
01190
01191
01192 if (old_block) {
01193
01194 MEM_PURE_STACK* tmp_stack = MEM_POOL_pure_stack(pool);
01195 MEM_PTR cur = (MEM_PTR) ((size_t) old_block - 8);
01196 Is_True (tmp_stack, ("MEM_POOL_Realloc %s: missing stack",
01197 MEM_POOL_name(pool)));
01198 while (tmp_stack) {
01199 MEM_PTR tmp = MEM_PURE_STACK_last_alloc(tmp_stack);
01200 MEM_PTR prev = NULL;
01201
01202 while (tmp && (tmp != cur)) {
01203 prev = tmp;
01204 tmp = *((MEM_PTR*) tmp);
01205 }
01206 if (tmp) {
01207 foundit = TRUE;
01208
01209 if (prev) *(MEM_PTR*) prev = *(MEM_PTR*) tmp;
01210 else MEM_PURE_STACK_last_alloc(tmp_stack) = *(MEM_PTR*) tmp;
01211 break;
01212 }
01213 tmp_stack = MEM_PURE_STACK_prev_stack(tmp_stack);
01214 }
01215 }
01216 if (old_block && !foundit) {
01217 DevWarn ("Realloc without a previous alloc, pool %s, 0x%p",
01218 MEM_POOL_name(pool), old_block);
01219
01220 ret_val = (MEM_PTR) malloc (new_size+8);
01221 memmove((MEM_PTR) (((size_t) ret_val)+8), old_block, old_size);
01222 }
01223 else {
01224
01225 ret_val = (MEM_PTR)
01226 realloc((MEM_PTR) (old_block ? (size_t) old_block-8 : 0),
01227 new_size+8);
01228 }
01229 if (new_size > 0) {
01230 FmtAssert (ret_val, ("oops - realloc returned NULL, pool %s\n",
01231 MEM_POOL_name(pool)));
01232 *(MEM_PTR*) ret_val = MEM_POOL_last_alloc(pool);
01233 MEM_POOL_last_alloc(pool) = ret_val;
01234 ret_val = (MEM_PTR) ((size_t) ret_val + 8);
01235 if ( old_size < new_size )
01236 memset((char*)ret_val + old_size, '\0', new_size - old_size);
01237 }
01238 if (purify_pools_trace)
01239 printf ("pool %s, realloc 0x%p, new size %llu, (0x%p - 0x%p)\n",
01240 MEM_POOL_name(pool), ret_val, (UINT64)new_size,
01241 ret_val, (char *)ret_val + new_size - 8);
01242 return ret_val;
01243 }
01244
01245 Is_True(MEM_POOL_blocks(pool) != NULL,
01246 ("Alloc with uninitialized MEM_POOL"));
01247 #ifdef Is_True_On
01248 if ( mem_tracing_enabled )
01249 Site_Account_Alloc(pool,old_size,new_size,line,file);
01250 #endif
01251
01252
01253
01254 old_size = PAD_TO_ALIGN(old_size);
01255 new_size = PAD_TO_ALIGN(new_size);
01256
01257
01258
01259 if ( new_size == old_size )
01260 return old_block;
01261
01262 #if 0
01263 #ifdef Is_True_On
01264 if (new_size < old_size)
01265 DevWarn ("MEMORY: shrinking an object in (%s) from %d to %d bytes",
01266 MEM_POOL_name(pool), old_size, new_size);
01267 else if (new_size < old_size * 1.5 && old_size > 256)
01268 DevWarn ("MEMORY: small grow from %d to %d bytes (mempool: %s)",
01269 old_size, new_size, MEM_POOL_name(pool));
01270 #endif
01271 #endif
01272
01273 if (old_size <= MIN_LARGE_BLOCK_SIZE) {
01274 if (new_size < old_size)
01275 return old_block;
01276 else {
01277 result = Raw_Allocate (pool, new_size);
01278 memmove (result, old_block, old_size);
01279 return result;
01280 }
01281 } else {
01282 MEM_LARGE_BLOCK *large_block = (MEM_LARGE_BLOCK *)
01283 (((char *) old_block) - MEM_LARGE_BLOCK_OVERHEAD);
01284 if (MEM_LARGE_BLOCK_ptr(large_block) == (MEM_PTR) old_block &&
01285 MEM_LARGE_BLOCK_base(large_block) == MEM_POOL_blocks(pool)) {
01286
01287 if (new_size <= MIN_LARGE_BLOCK_SIZE) {
01288 result = Raw_Allocate (pool, new_size);
01289 memmove (result, old_block, new_size);
01290 MEM_POOL_FREE (pool, old_block);
01291 return result;
01292 } else {
01293 MEM_LARGE_BLOCK *p =
01294 (MEM_LARGE_BLOCK *)(((char *)old_block) - MEM_LARGE_BLOCK_OVERHEAD);
01295
01296 large_block =
01297 MEM_LARGE_BLOCK_realloc(p, new_size + MEM_LARGE_BLOCK_OVERHEAD);
01298
01299 if (large_block == NULL)
01300 ErrMsg (EC_No_Mem, "MEM_POOL_Realloc");
01301 MEM_LARGE_BLOCK_ptr(large_block) = (MEM_PTR)
01302 (((char *)large_block) + MEM_LARGE_BLOCK_OVERHEAD);
01303 if (MEM_POOL_bz(pool)) {
01304 memset (((char *) MEM_LARGE_BLOCK_ptr(large_block)) + old_size,
01305 '\0', new_size - old_size);
01306 }
01307 p = MEM_LARGE_BLOCK_prev(large_block);
01308 if (p == NULL)
01309 MEM_POOL_large_block(pool) = large_block;
01310 else
01311 MEM_LARGE_BLOCK_next(p) = large_block;
01312 p = MEM_LARGE_BLOCK_next(large_block);
01313 if (p)
01314 MEM_LARGE_BLOCK_prev(p) = large_block;
01315 return MEM_LARGE_BLOCK_ptr(large_block);
01316 }
01317 } else {
01318 result = Raw_Allocate (pool, new_size);
01319 if (new_size > old_size)
01320 memmove (result, old_block, old_size);
01321 else
01322 memmove (result, old_block, new_size);
01323 return result;
01324 }
01325 }
01326 }
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341 void
01342 MEM_POOL_Push_P
01343 (
01344 MEM_POOL *pool
01345 MEM_STAT_ARGS(line,file)
01346 )
01347 {
01348 MEM_POOL_BLOCKS *pb;
01349
01350 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01351 ("Push before Initialize in MEM_POOL %s\n", MEM_POOL_name(pool)));
01352
01353 FmtAssert(MEM_POOL_frozen(pool) == FALSE, ("Pushing a frozen pool - %s.",
01354 MEM_POOL_name(pool)));
01355 if (pool == Default_Mem_Pool) pool = The_Default_Mem_Pool;
01356 if (pool == Malloc_Mem_Pool) return;
01357 #ifdef JUST_USE_MALLOC
01358 return;
01359 #endif
01360
01361 if (purify_pools) {
01362 MEM_PURE_STACK* tmp = (MEM_PURE_STACK*) malloc(sizeof(MEM_PURE_STACK));
01363 Is_True (tmp, ("MEM_POOL_Push %s: malloc stack returned NULL",
01364 MEM_POOL_name(pool)));
01365 MEM_PURE_STACK_last_alloc(tmp) = NULL;
01366 MEM_PURE_STACK_prev_stack(tmp) = MEM_POOL_pure_stack(pool);
01367 MEM_POOL_pure_stack(pool) = tmp;
01368 if (purify_pools_trace_x) {
01369 if (MEM_POOL_blocks(pool) == (MEM_POOL_BLOCKS *) MEM_POOL_INIT_IN_PROGRESS) {
01370 (void) printf("MEM_POOL_Push %s 0x%p<-- free push (called by M_P_Initialize)\n",
01371 MEM_POOL_name(pool), pool);
01372 }
01373 else {
01374 (void) printf ("MEM_POOL_Push %s 0x%p\n", MEM_POOL_name(pool), pool);
01375 }
01376 }
01377
01378
01379
01380
01381 MEM_POOL_blocks(pool) = (MEM_POOL_BLOCKS *) TRUE;
01382 return;
01383 }
01384
01385 #ifdef Is_True_On
01386 if ( mem_tracing_enabled )
01387 Site_Account_Push(pool,line,file);
01388 #endif
01389
01390 if ( free_mem_pool_blocks_list != NULL ) {
01391
01392
01393 pb = free_mem_pool_blocks_list;
01394 free_mem_pool_blocks_list = MEM_POOL_BLOCKS_rest(pb);
01395 } else {
01396
01397
01398 pb = TYPE_MEM_POOL_ALLOC(MEM_POOL_BLOCKS,&mem_overhead_pool);
01399 }
01400
01401 MEM_POOL_BLOCKS_rest(pb) = MEM_POOL_blocks(pool);
01402 MEM_POOL_BLOCKS_large_block(pb) = NULL;
01403 if (MEM_POOL_BLOCKS_rest(pb) == NULL) {
01404 MEM_POOL_BLOCKS_block(pb) = NULL;
01405 MEM_POOL_BLOCKS_base_block(pb) = NULL;
01406 MEM_POOL_BLOCKS_base_ptr(pb) = NULL;
01407 MEM_POOL_BLOCKS_base_avail(pb) = 0;
01408 } else {
01409 MEM_POOL_BLOCKS *p = MEM_POOL_BLOCKS_rest(pb);
01410 MEM_POOL_BLOCKS_block(pb) = MEM_POOL_BLOCKS_block(p);
01411 MEM_POOL_BLOCKS_base_block(pb) = MEM_POOL_BLOCKS_block(p);
01412 if (MEM_POOL_BLOCKS_block(p)) {
01413 MEM_POOL_BLOCKS_base_ptr(pb) = MEM_BLOCK_ptr(MEM_POOL_BLOCKS_block(p));
01414 MEM_POOL_BLOCKS_base_avail(pb) =
01415 MEM_BLOCK_avail(MEM_POOL_BLOCKS_block(p));
01416 } else {
01417 MEM_POOL_BLOCKS_base_ptr(pb) = NULL;
01418 MEM_POOL_BLOCKS_base_avail(pb) = 0;
01419 }
01420 }
01421 MEM_POOL_blocks(pool) = pb;
01422 }
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437 void
01438 MEM_POOL_Push_Freeze_P
01439 (
01440 MEM_POOL *pool
01441 MEM_STAT_ARGS(line,file)
01442 )
01443 {
01444 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01445 ("Push_Freeze before Initialize in MEM_POOL %s\n", MEM_POOL_name(pool)));
01446 FmtAssert (MEM_POOL_frozen(pool) == FALSE,
01447 ("Cannot Push_Freeze a frozen pool - %s.", MEM_POOL_name(pool)));
01448 if (purify_pools_trace_x)
01449 printf ("MEM_POOL_Push_Freeze %s -- \n", MEM_POOL_name(pool));
01450 MEM_POOL_Push_P (pool, line, file);
01451 MEM_POOL_frozen(pool) = TRUE;
01452 }
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467 void
01468 MEM_POOL_Pop_P
01469 (
01470 MEM_POOL *pool
01471 MEM_STAT_ARGS(line,file)
01472 )
01473 {
01474 MEM_BLOCK *bp, *next_bp;
01475 MEM_LARGE_BLOCK *lbp, *next_lbp;
01476 MEM_POOL_BLOCKS *bsp;
01477
01478 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01479 ("Pop before Initialize in MEM_POOL %s\n", MEM_POOL_name(pool)));
01480
01481 FmtAssert(MEM_POOL_frozen(pool) == FALSE, ("Popping a frozen pool - %s.",
01482 MEM_POOL_name(pool)));
01483 if (pool == Default_Mem_Pool) pool = The_Default_Mem_Pool;
01484 if (pool == Malloc_Mem_Pool) return;
01485
01486 #ifdef JUST_USE_MALLOC
01487 return;
01488 #endif
01489 if (purify_pools) {
01490 MEM_PURE_STACK *tmp_stack;
01491 MEM_PTR tmp = NULL;
01492 MEM_PTR next = NULL;
01493 Is_True (MEM_POOL_pure_stack(pool),
01494 ("Pop, but no push stack on %s", MEM_POOL_name(pool)));
01495 if (purify_pools_trace_x)
01496 printf ("MEM_POOL_Pop %s 0x%p\n", MEM_POOL_name(pool), pool);
01497 tmp = MEM_POOL_last_alloc(pool);
01498 while (tmp) {
01499 next = (*(MEM_PTR*) tmp);
01500 if (purify_pools_trace) printf ("pool %s, pop-free 0x%p\n",
01501 MEM_POOL_name(pool), (char *)tmp+8);
01502 free (tmp);
01503 tmp = next;
01504 }
01505 tmp_stack = MEM_POOL_prev_stack(pool);
01506 free (MEM_POOL_pure_stack(pool));
01507 MEM_POOL_pure_stack(pool) = tmp_stack;
01508 return;
01509 }
01510
01511 bsp = MEM_POOL_blocks(pool);
01512
01513 FmtAssert(MEM_POOL_blocks(pool),("Freeing an uninitialized pool."));
01514
01515 #ifdef Is_True_On
01516 if ( mem_tracing_enabled )
01517 Site_Account_Pop(pool,line,file);
01518 #endif
01519
01520 for (bp = MEM_POOL_BLOCKS_block(bsp); bp; bp = next_bp) {
01521 next_bp = MEM_BLOCK_rest(bp);
01522
01523 #if Is_True_On
01524 if (special_address >= (char *) MEM_BLOCK_first_ptr(bp) &&
01525 special_address < ((char *) MEM_BLOCK_ptr(bp) +
01526 MEM_BLOCK_avail(bp))) {
01527 fprintf(TFile, "Pool %s freed %llu bytes from 0x%p to 0x%p\n",
01528 MEM_POOL_name(pool),
01529 (UINT64)(MEM_BLOCK_avail(bp) +
01530 (char *) MEM_BLOCK_ptr(bp) -
01531 (char *) MEM_BLOCK_first_ptr(bp)),
01532 (char *) MEM_BLOCK_first_ptr(bp),
01533 (char *) MEM_BLOCK_ptr(bp) + MEM_BLOCK_avail(bp));
01534 special_address_owner = "NOBODY";
01535 }
01536 #endif
01537
01538 if (bp == MEM_POOL_BLOCKS_base_block(bsp)) {
01539 MEM_BLOCK_ptr(bp) = MEM_POOL_BLOCKS_base_ptr(bsp);
01540 MEM_BLOCK_avail(bp) = MEM_POOL_BLOCKS_base_avail(bsp);
01541 if (MEM_POOL_bz(pool))
01542 memset (MEM_BLOCK_ptr(bp), '\0', MEM_BLOCK_avail(bp));
01543 break;
01544 }
01545 free (bp);
01546 }
01547
01548 for (lbp = MEM_POOL_BLOCKS_large_block(bsp); lbp; lbp = next_lbp) {
01549 next_lbp = MEM_LARGE_BLOCK_next(lbp);
01550 MEM_LARGE_BLOCK_free(lbp);
01551 }
01552
01553
01554
01555
01556
01557
01558
01559
01560 if ( MEM_POOL_BLOCKS_rest(bsp) != NULL ) {
01561 MEM_POOL_blocks(pool) = MEM_POOL_BLOCKS_rest(bsp);
01562 MEM_POOL_BLOCKS_rest(bsp) = free_mem_pool_blocks_list;
01563 free_mem_pool_blocks_list = bsp;
01564 } else {
01565 memset (bsp, '\0', sizeof(MEM_POOL_BLOCKS));
01566 }
01567 }
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582 void
01583 MEM_POOL_Pop_Unfreeze_P
01584 (
01585 MEM_POOL *pool
01586 MEM_STAT_ARGS(line,file)
01587 )
01588 {
01589 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01590 ("Pop_Unfreeze before Initialize in MEM_POOL %s\n", MEM_POOL_name(pool)));
01591 FmtAssert (MEM_POOL_frozen(pool) == TRUE,
01592 ("Cannot Pop_Unfreeze a non-frozen pool - %s.",
01593 MEM_POOL_name(pool)));
01594 MEM_POOL_frozen(pool) = FALSE;
01595 if (purify_pools_trace_x)
01596 printf ("MEM_POOL_Pop_Unfreeze %s -- \n", MEM_POOL_name(pool));
01597 MEM_POOL_Pop_P (pool, line, file);
01598 }
01599
01600 void MEM_POOL_Set_Default(MEM_POOL *pool)
01601 {
01602 The_Default_Mem_Pool = pool;
01603 }
01604
01605 void MEM_POOL_FREE(MEM_POOL *pool, void *data)
01606 {
01607 MEM_LARGE_BLOCK *large_block;
01608
01609 if (data == NULL)
01610 return;
01611
01612 if (pool == Default_Mem_Pool) pool = The_Default_Mem_Pool;
01613 if (pool == Malloc_Mem_Pool) {
01614 free(data);
01615 return;
01616 }
01617
01618 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01619 ("Free into un-initialized MEM_POOL %s\n", MEM_POOL_name(pool)));
01620
01621 #ifdef JUST_USE_MALLOC
01622 return;
01623 #endif
01624 if (data && purify_pools) {
01625 BOOL foundit = FALSE;
01626
01627 MEM_PURE_STACK* tmp_stack = MEM_POOL_pure_stack(pool);
01628 MEM_PTR cur = (MEM_PTR) ((size_t) data - 8);
01629 Is_True (tmp_stack, ("MEM_POOL_Realloc %s: missing stack",
01630 MEM_POOL_name(pool)));
01631 while (tmp_stack) {
01632 MEM_PTR tmp = MEM_PURE_STACK_last_alloc(tmp_stack);
01633 MEM_PTR prev = NULL;
01634
01635 while (tmp && (tmp != cur)) {
01636 prev = tmp;
01637 tmp = *((MEM_PTR*) tmp);
01638 }
01639 if (tmp) {
01640 foundit = TRUE;
01641
01642 if (prev) *(MEM_PTR*) prev = *(MEM_PTR*) tmp;
01643 else MEM_PURE_STACK_last_alloc(tmp_stack) = *(MEM_PTR*) tmp;
01644 break;
01645 }
01646 tmp_stack = MEM_PURE_STACK_prev_stack(tmp_stack);
01647 }
01648 if (purify_pools_trace)
01649 printf ("pool %s, free 0x%p\n", MEM_POOL_name(pool), data);
01650 if (!foundit) {
01651
01652 free (cur);
01653 FmtAssert(FALSE,("MEM_POOL_FREE: pool %s, could not find pointer 0x%p\n",
01654 MEM_POOL_name(pool), data));
01655 }
01656 free (cur);
01657 return;
01658 }
01659
01660 large_block = (MEM_LARGE_BLOCK *)
01661 (((char *) data) - MEM_LARGE_BLOCK_OVERHEAD);
01662 if (MEM_LARGE_BLOCK_ptr(large_block) == (MEM_PTR) data) {
01663 MEM_LARGE_BLOCK *prev;
01664 MEM_LARGE_BLOCK *next;
01665 if (MEM_LARGE_BLOCK_base(large_block) != MEM_POOL_blocks(pool))
01666 return;
01667
01668 prev = MEM_LARGE_BLOCK_prev(large_block);
01669 next = MEM_LARGE_BLOCK_next(large_block);
01670 if (prev == NULL)
01671 MEM_POOL_large_block(pool) = next;
01672 else
01673 MEM_LARGE_BLOCK_next(prev) = next;
01674
01675 if (next)
01676 MEM_LARGE_BLOCK_prev(next) = prev;
01677
01678 MEM_LARGE_BLOCK_free(large_block);
01679 }
01680
01681 }
01682
01683 #ifdef Is_True_On
01684 static void
01685 trace_initialized_pool (char *msg, char *pname)
01686 {
01687 MEM_POOL **listp = &initialized_pools;
01688 printf("<%s %s> initialized_pools: ", msg, pname);
01689 while (*listp != NULL) {
01690 printf(", %s", MEM_POOL_name(*listp));
01691 listp = &MEM_POOL_rest(*listp);
01692 }
01693 printf("\n");
01694 }
01695 #endif
01696
01697 void MEM_POOL_Delete(MEM_POOL *pool)
01698 {
01699 MEM_POOL_BLOCKS *bsp;
01700
01701 if (pool == Default_Mem_Pool) pool = The_Default_Mem_Pool;
01702 if (pool == Malloc_Mem_Pool) return;
01703
01704 #ifdef Is_True_On
01705
01706
01707
01708
01709
01710
01711
01712 if ( mem_tracing_enabled ) {
01713 MEM_POOL **listp = &initialized_pools;
01714
01715 if (*listp == pool) {
01716 initialized_pools = MEM_POOL_rest(pool);
01717 }
01718 else {
01719 while (*listp && MEM_POOL_rest(*listp)) {
01720 if (MEM_POOL_rest(*listp) == pool) break;
01721 listp = &MEM_POOL_rest(*listp);
01722 }
01723 if (*listp && MEM_POOL_rest(*listp)) {
01724
01725 MEM_POOL_rest(*listp) = MEM_POOL_rest(pool);
01726 }
01727 else {
01728 DevWarn("didn't find pool %s in initialized_pools", MEM_POOL_name(pool));
01729 }
01730 }
01731 Is_True(!MEM_STAT_In_List( initialized_pools, pool ),
01732 ("Pool still in initialized list"));
01733 }
01734 #endif
01735
01736 Is_True (MEM_POOL_magic_num(pool) == MAGIC_NUM,
01737 ("Deleting a pool that has not been initialized: %s\n",
01738 MEM_POOL_name(pool)));
01739
01740 if (purify_pools) {
01741
01742 #ifndef TODO_REMOVE_FREE_PUSH
01743 if (!MEM_POOL_pure_stack(pool)) {
01744 DevWarn("During MEM_POOL_Delete: Too many pops on %s.",
01745 MEM_POOL_name(pool));
01746 }
01747 else {
01748 MEM_POOL_Pop(pool);
01749 #endif
01750 if (MEM_POOL_pure_stack(pool)) {
01751 DevWarn("During MEM_POOL_Delete: Too few pops on %s.",
01752 MEM_POOL_name(pool));
01753 while (MEM_POOL_pure_stack(pool))
01754 MEM_POOL_Pop(pool);
01755 }
01756 #ifndef TODO_REMOVE_FREE_PUSH
01757 }
01758 #endif
01759 if (purify_pools_trace_x)
01760 printf ("MEM_POOL_Delete %s 0x%p\n", MEM_POOL_name(pool), pool);
01761 MEM_POOL_magic_num(pool) = 0;
01762 return;
01763 }
01764
01765
01766
01767
01768
01769 while (MEM_POOL_BLOCKS_rest(MEM_POOL_blocks(pool)) != NULL)
01770 MEM_POOL_Pop(pool);
01771 MEM_POOL_Pop(pool);
01772 bsp = MEM_POOL_blocks(pool);
01773 MEM_POOL_BLOCKS_rest(bsp) = free_mem_pool_blocks_list;
01774 free_mem_pool_blocks_list = bsp;
01775
01776 memset (pool, '\0', sizeof(MEM_POOL));
01777 MEM_POOL_magic_num(pool) = 0;
01778 }
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796 void
01797 MEM_POOL_Initialize_P
01798 (
01799 MEM_POOL *pool,
01800 const char *name,
01801 BOOL memzero
01802 MEM_STAT_ARGS(line,file)
01803 )
01804 {
01805 if (pool == Default_Mem_Pool) pool = The_Default_Mem_Pool;
01806 if (pool == Malloc_Mem_Pool) return;
01807
01808 MEM_POOL_name(pool) = name;
01809 MEM_POOL_bz(pool) = memzero;
01810 MEM_POOL_blocks(pool) = NULL;
01811 MEM_POOL_frozen(pool) = FALSE;
01812 MEM_POOL_pure_stack(pool) = NULL;
01813
01814
01815 Is_True (MEM_POOL_magic_num(pool) != MAGIC_NUM,
01816 ("Initialization of an already initialized pool: %s\n",
01817 MEM_POOL_name(pool)));
01818 MEM_POOL_magic_num(pool) = MAGIC_NUM;
01819
01820 if (purify_pools_trace_x)
01821 printf ("MEM_POOL_Initialize %s 0x%p\n", MEM_POOL_name(pool), pool);
01822
01823 #ifdef Is_True_On
01824 MEM_POOL_alloc_site_list(pool) = NULL;
01825 if ( mem_tracing_enabled ) {
01826 if ( ! MEM_STAT_In_List( initialized_pools, pool ) ) {
01827
01828 MEM_POOL_rest(pool) = initialized_pools;
01829 initialized_pools = pool;
01830 }
01831 }
01832 #endif
01833
01834 if (purify_pools) {
01835 MEM_POOL_blocks(pool) = (MEM_POOL_BLOCKS *) MEM_POOL_INIT_IN_PROGRESS;
01836 }
01837
01838 #ifndef TODO_REMOVE_FREE_PUSH
01839 MEM_POOL_Push(pool);
01840 #endif
01841
01842 if (purify_pools) {
01843
01844
01845
01846 MEM_POOL_blocks(pool) = NULL;
01847 }
01848 }
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860 void
01861 MEM_Initialize(void)
01862 {
01863 const char* ppools = getenv ("PURIFY_MEMPOOLS");
01864 if (ppools) {
01865 if (((ppools[0] == 'O') || (ppools[0] == 'o')) &&
01866 ((ppools[1] == 'N') || (ppools[1] == 'n'))) {
01867 purify_pools = TRUE;
01868 if ((ppools[2] == '-') &&
01869 ((ppools[3] == 'T') || (ppools[3] == 't')) &&
01870 ((ppools[4] == 'R') || (ppools[4] == 'r')) &&
01871 ((ppools[5] == 'A') || (ppools[5] == 'a')) &&
01872 ((ppools[6] == 'C') || (ppools[6] == 'c')) &&
01873 ((ppools[7] == 'E') || (ppools[7] == 'e'))) {
01874 purify_pools_trace = TRUE;
01875 if ((ppools[8] == '-') &&
01876 ((ppools[9] == 'X') || (ppools[9] == 'x'))) {
01877 purify_pools_trace_x = TRUE;
01878 if ((ppools[10] == '-') &&
01879 ((ppools[11] == 'O') || (ppools[11] == 'o')) &&
01880 ((ppools[12] == 'N') || (ppools[12] == 'n')) &&
01881 ((ppools[13] == 'L') || (ppools[13] == 'l')) &&
01882 ((ppools[14] == 'Y') || (ppools[14] == 'y'))) {
01883 purify_pools_trace = FALSE;
01884 DevWarn("Using purify memory pools, limited extended tracing ###");
01885 } else
01886 DevWarn ("Using purify memory pools, with extended tracing ###");
01887 }
01888 else
01889 DevWarn ("Using purify memory pools, with tracing ###");
01890 }
01891 else DevWarn ("Using purify memory pools ###");
01892 }
01893 else if (((ppools[0] == 'O') || (ppools[0] == 'o')) &&
01894 ((ppools[1] == 'F') || (ppools[1] == 'f')) &&
01895 ((ppools[2] == 'F') || (ppools[2] == 'f'))) {
01896 purify_pools = FALSE;
01897 }
01898 else DevWarn ("PURIFY_MEMPOOLS set to garbage, using regular pools");
01899 }
01900
01901 MEM_POOL_Initialize(&MEM_local_pool,"Local",TRUE);
01902 MEM_POOL_Initialize(&MEM_src_pool,"Source",TRUE);
01903 MEM_POOL_Initialize(&MEM_pu_pool,"Program unit",TRUE);
01904 MEM_POOL_Initialize(&MEM_phase_pool,"Phase",TRUE);
01905
01906 MEM_POOL_Push(&MEM_local_pool);
01907 MEM_POOL_Push(&MEM_src_pool);
01908 MEM_POOL_Push(&MEM_pu_pool);
01909 MEM_POOL_Push(&MEM_phase_pool);
01910
01911 MEM_POOL_Initialize(&MEM_local_nz_pool,"Local (nz)",FALSE);
01912 MEM_POOL_Initialize(&MEM_src_nz_pool,"Source (nz)",FALSE);
01913 MEM_POOL_Initialize(&MEM_pu_nz_pool,"Program unit (nz)",FALSE);
01914 MEM_POOL_Initialize(&MEM_phase_nz_pool,"Phase (nz)",FALSE);
01915
01916 MEM_POOL_Push(&MEM_local_nz_pool);
01917 MEM_POOL_Push(&MEM_src_nz_pool);
01918 MEM_POOL_Push(&MEM_pu_nz_pool);
01919 MEM_POOL_Push(&MEM_phase_nz_pool);
01920
01921 }
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954 MEM_PTR
01955 Realloc_Clear ( MEM_PTR ptr, INT32 new_size, INT32 old_size )
01956 {
01957 MEM_PTR result = (MEM_PTR) realloc ( ptr, new_size );
01958
01959 if ( result == NULL )
01960 ErrMsg ( EC_No_Mem, "Realloc_Clear" );
01961
01962
01963 if ( new_size > old_size ) {
01964 MEM_PTR start_of_new = (MEM_PTR) ( ((char *) result) + old_size );
01965 INT32 num_added_bytes = new_size - old_size;
01966 memset ( start_of_new, '\0', num_added_bytes );
01967 }
01968
01969 return result;
01970 }
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999 MEM_PTR
02000 Re_Calloc ( MEM_PTR ptr, INT32 new_nelem, INT32 elsize, INT32 old_nelem )
02001 {
02002 return Realloc_Clear ( ptr, new_nelem * elsize, old_nelem * elsize );
02003 }