00001
00002
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #ifndef _GNU_SOURCE
00047 # define _GNU_SOURCE
00048 #endif
00049 #ifndef __USE_GNU
00050 # define __USE_GNU
00051 #endif
00052
00053 #include <stdio.h>
00054 #include <stdlib.h>
00055 #include <string.h>
00056
00057 #ifndef __STDC_FORMAT_MACROS
00058 # define __STDC_FORMAT_MACROS
00059 #endif
00060 #ifndef __STDC_LIMIT_MACROS
00061 # define __STDC_LIMIT_MACROS
00062 #endif
00063 #include <inttypes.h>
00064 #ifndef _WIN32
00065 # include <unistd.h>
00066 #else
00067 # include <process.h>
00068 # define getpid _getpid
00069 #endif
00070 #include "converse.h"
00071 #include "charm-api.h"
00072
00073 void * memory_stack_top;
00074 int cpdInSystem=1;
00075
00076
00077 #if CMK_MEMORY_BUILD_DEFAULT
00078
00079 # if CMK_MALLOC_USE_OS_BUILTIN
00080
00081 # define CMK_MEMORY_BUILD_OS 1
00082
00083 # else
00084
00085 # define CMK_MEMORY_BUILD_GNU 1
00086 # endif
00087
00088 #endif
00089
00090 #if CMK_MEMORY_BUILD_OS_WRAPPED
00091 #define CMK_MEMORY_BUILD_OS 1
00092 #endif
00093 #if CMK_MEMORY_BUILD_GNU_HOOKS
00094
00095
00096 #define CMK_MEMORY_BUILD_OS 1
00097 #endif
00098
00099 #if CMK_MEMORY_BUILD_OS
00100 #if CMK_MEMORY_BUILD_OS_WRAPPED
00101
00102 struct mallinfo;
00103
00104 void initialize_memory_wrapper(void);
00105 void * initialize_memory_wrapper_calloc(size_t nelem, size_t size);
00106 void * initialize_memory_wrapper_malloc(size_t size);
00107 void * initialize_memory_wrapper_realloc(void *ptr, size_t size);
00108 void * initialize_memory_wrapper_memalign(size_t align, size_t size);
00109 int initialize_memory_wrapper_posix_memalign(void **memptr, size_t align, size_t size);
00110 void * initialize_memory_wrapper_aligned_alloc(size_t align, size_t size);
00111 void * initialize_memory_wrapper_valloc(size_t size);
00112 void * initialize_memory_wrapper_pvalloc(size_t size);
00113 void initialize_memory_wrapper_free(void *ptr);
00114 void initialize_memory_wrapper_cfree(void *ptr);
00115
00116 void * (*mm_malloc)(size_t) = initialize_memory_wrapper_malloc;
00117 void * (*mm_calloc)(size_t,size_t) = initialize_memory_wrapper_calloc;
00118 void * (*mm_realloc)(void*,size_t) = initialize_memory_wrapper_realloc;
00119 void * (*mm_memalign)(size_t,size_t) = initialize_memory_wrapper_memalign;
00120 int (*mm_posix_memalign)(void **,size_t,size_t) = initialize_memory_wrapper_posix_memalign;
00121 void * (*mm_aligned_alloc)(size_t,size_t) = initialize_memory_wrapper_aligned_alloc;
00122 void * (*mm_valloc)(size_t) = initialize_memory_wrapper_valloc;
00123 void * (*mm_pvalloc)(size_t) = initialize_memory_wrapper_pvalloc;
00124 void (*mm_free)(void*) = initialize_memory_wrapper_free;
00125 void (*mm_cfree)(void*) = initialize_memory_wrapper_cfree;
00126 struct mallinfo (*mm_mallinfo)(void) = NULL;
00127
00128 static char fake_malloc_buffer[1024];
00129 static char* fake_malloc_buffer_pos = fake_malloc_buffer;
00130
00131 static void* fake_malloc(size_t size)
00132 {
00133 void *ptr = fake_malloc_buffer_pos;
00134 fake_malloc_buffer_pos += size;
00135 if (fake_malloc_buffer_pos > fake_malloc_buffer + sizeof(fake_malloc_buffer))
00136 {
00137 static char have_warned = 0;
00138 if (!have_warned)
00139 {
00140 have_warned = 1;
00141 CmiPrintf("Error: fake_malloc has run out of space (%u / %u)\n",
00142 (unsigned int) (fake_malloc_buffer_pos - fake_malloc_buffer),
00143 (unsigned int) sizeof(fake_malloc_buffer));
00144 }
00145 exit(1);
00146 }
00147 return ptr;
00148 }
00149 static void* fake_calloc(size_t nelem, size_t size)
00150 {
00151 const size_t total = nelem * size;
00152 void *ptr = fake_malloc(total);
00153 memset(ptr, 0, total);
00154 return ptr;
00155 }
00156 #if 0
00157 static void fake_free(void* ptr)
00158 {
00159 }
00160 #endif
00161
00162 extern char initialize_memory_wrapper_status;
00163
00164 void * initialize_memory_wrapper_calloc(size_t nelem, size_t size) {
00165 if (initialize_memory_wrapper_status)
00166 return fake_calloc(nelem, size);
00167 initialize_memory_wrapper();
00168 return (*mm_calloc)(nelem,size);
00169 }
00170
00171 void * initialize_memory_wrapper_malloc(size_t size) {
00172 if (initialize_memory_wrapper_status)
00173 return fake_malloc(size);
00174 initialize_memory_wrapper();
00175 return (*mm_malloc)(size);
00176 }
00177
00178 void * initialize_memory_wrapper_realloc(void *ptr, size_t size) {
00179 initialize_memory_wrapper();
00180 return (*mm_realloc)(ptr,size);
00181 }
00182
00183 void * initialize_memory_wrapper_memalign(size_t align, size_t size) {
00184 initialize_memory_wrapper();
00185 return (*mm_memalign)(align,size);
00186 }
00187
00188 int initialize_memory_wrapper_posix_memalign(void **memptr, size_t align, size_t size) {
00189 initialize_memory_wrapper();
00190 return (*mm_posix_memalign)(memptr,align,size);
00191 }
00192
00193 void * initialize_memory_wrapper_aligned_alloc(size_t align, size_t size) {
00194 initialize_memory_wrapper();
00195 return (*mm_aligned_alloc)(align,size);
00196 }
00197
00198 void * initialize_memory_wrapper_valloc(size_t size) {
00199 initialize_memory_wrapper();
00200 return (*mm_valloc)(size);
00201 }
00202
00203 void * initialize_memory_wrapper_pvalloc(size_t size) {
00204 initialize_memory_wrapper();
00205 return (*mm_pvalloc)(size);
00206 }
00207
00208 void initialize_memory_wrapper_free(void *ptr) {
00209 if (initialize_memory_wrapper_status)
00210 return;
00211 initialize_memory_wrapper();
00212 (*mm_free)(ptr);
00213 }
00214
00215 void initialize_memory_wrapper_cfree(void *ptr) {
00216 initialize_memory_wrapper();
00217 (*mm_cfree)(ptr);
00218 }
00219
00220 #define mm_malloc (*mm_malloc)
00221 #define mm_free (*mm_free)
00222 #define mm_calloc (*mm_calloc)
00223 #define mm_cfree (*mm_cfree)
00224 #define mm_realloc (*mm_realloc)
00225 #define mm_memalign (*mm_memalign)
00226 #define mm_posix_memalign (*mm_posix_memalign)
00227 #define mm_aligned_alloc (*mm_aligned_alloc)
00228 #define mm_valloc (*mm_valloc)
00229 #define mm_pvalloc (*mm_pvalloc)
00230
00231 #else
00232 #define mm_malloc malloc
00233 #define mm_calloc calloc
00234 #define mm_memalign memalign
00235 #define mm_posix_memalign posix_memalign
00236 #if (defined __cplusplus && __cplusplus >= 201703L) || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L)
00237 #define mm_aligned_alloc aligned_alloc
00238 #else
00239 #define mm_aligned_alloc memalign
00240 #endif
00241 #define mm_free free
00242 #endif
00243 #endif
00244
00245 CMK_TYPEDEF_UINT8 _memory_allocated = 0;
00246 CMK_TYPEDEF_UINT8 _memory_allocated_max = 0;
00247 CMK_TYPEDEF_UINT8 _memory_allocated_min = 0;
00248
00249
00250
00251
00252 static int rank_holding_CmiMemLock=-1;
00253
00254
00255 static int CmiMemoryIs_flag=0;
00256
00257 int CmiMemoryIs(int flag)
00258 {
00259 return (CmiMemoryIs_flag&flag)==flag;
00260 }
00261
00267 static char *memory_lifeRaft=NULL;
00268
00269 void CmiOutOfMemoryInit(void);
00270
00271 void CmiOutOfMemory(int nBytes)
00272 {
00273 char errMsg[200];
00274 if (memory_lifeRaft) free(memory_lifeRaft);
00275 if (nBytes>0) sprintf(errMsg,"Could not malloc() %d bytes--are we out of memory? (used :%.3fMB)",nBytes,CmiMemoryUsage()/1000000.0);
00276 else sprintf(errMsg,"Could not malloc()--are we out of memory? (used: %.3fMB)", CmiMemoryUsage()/1000000.0);
00277 CmiAbort(errMsg);
00278 }
00279
00280
00281 int memory_status_info=0;
00282 int memory_chare_id=0;
00283
00284 #if CMK_MEMORY_BUILD_OS
00285
00286
00287
00288 #ifdef __GNUC__
00289 #pragma GCC diagnostic push
00290 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
00291 #endif
00292 #ifdef __INTEL_COMPILER
00293 #pragma warning push
00294 #pragma warning disable 1478
00295 #endif
00296
00297 #if CMK_MEMORY_BUILD_OS_WRAPPED || CMK_MEMORY_BUILD_GNU_HOOKS
00298
00299 #if CMK_MEMORY_BUILD_GNU_HOOKS
00300
00301 static void *meta_malloc(size_t);
00302 static void *meta_realloc(void*,size_t);
00303 static void *meta_memalign(size_t,size_t);
00304 static void meta_free(void*);
00305 static void *meta_malloc_hook(size_t s, const void* c) {return meta_malloc(s);}
00306 static void *meta_realloc_hook(void* p,size_t s, const void* c) {return meta_realloc(p,s);}
00307 static void *meta_memalign_hook(size_t s1,size_t s2, const void* c) {return meta_memalign(s1,s2);}
00308 static void meta_free_hook(void* p, const void* c) {meta_free(p);}
00309
00310 #define BEFORE_MALLOC_CALL \
00311 __malloc_hook = old_malloc_hook; \
00312 __realloc_hook = old_realloc_hook; \
00313 __memalign_hook = old_memalign_hook; \
00314 __free_hook = old_free_hook;
00315 #define AFTER_MALLOC_CALL \
00316 old_malloc_hook = __malloc_hook; \
00317 old_realloc_hook = __realloc_hook; \
00318 old_memalign_hook = __memalign_hook; \
00319 old_free_hook = __free_hook; \
00320 __malloc_hook = meta_malloc_hook; \
00321 __realloc_hook = meta_realloc_hook; \
00322 __memalign_hook = meta_memalign_hook; \
00323 __free_hook = meta_free_hook;
00324
00325 #if CMK_HAS_MALLOC_H
00326 #include <malloc.h>
00327 #endif
00328 static void *(*old_malloc_hook) (size_t, const void*);
00329 static void *(*old_realloc_hook) (void*,size_t, const void*);
00330 static void *(*old_memalign_hook) (size_t,size_t, const void*);
00331 static void (*old_free_hook) (void*, const void*);
00332
00333 #else
00334 #define BEFORE_MALLOC_CALL
00335 #define AFTER_MALLOC_CALL
00336 #endif
00337
00338 #if CMK_MEMORY_BUILD_VERBOSE
00339 #include "memory-verbose.C"
00340 #endif
00341
00342 #if CMK_MEMORY_BUILD_PARANOID
00343 #include "memory-paranoid.C"
00344 #endif
00345
00346 #if CMK_MEMORY_BUILD_LEAK
00347 #include "memory-leak.C"
00348 #endif
00349
00350 #if CMK_MEMORY_BUILD_ISOMALLOC
00351 #include "memory-isomalloc.C"
00352 #endif
00353
00354 #if CMK_MEMORY_BUILD_LOCK
00355 #include "memory-lock.C"
00356 #endif
00357
00358 #if CMK_MEMORY_BUILD_CHARMDEBUG
00359 #include "memory-charmdebug.C"
00360 #endif
00361
00362 #if CMK_MEMORY_BUILD_GNU_HOOKS
00363
00364 static void
00365 my_init_hook (void)
00366 {
00367 old_malloc_hook = __malloc_hook;
00368 old_realloc_hook = __realloc_hook;
00369 old_memalign_hook = __memalign_hook;
00370 old_free_hook = __free_hook;
00371 __malloc_hook = meta_malloc_hook;
00372 __realloc_hook = meta_realloc_hook;
00373 __memalign_hook = meta_memalign_hook;
00374 __free_hook = meta_free_hook;
00375 }
00376
00377 #if defined(__MALLOC_HOOK_VOLATILE)
00378 void (* __MALLOC_HOOK_VOLATILE __malloc_initialize_hook) (void) = my_init_hook;
00379 #else
00380 void (* __malloc_initialize_hook) (void) = my_init_hook;
00381 #endif
00382 #else
00383 void *malloc(size_t size) CMK_THROW { return meta_malloc(size); }
00384 void free(void *ptr) CMK_THROW { meta_free(ptr); }
00385 void *calloc(size_t nelem, size_t size) CMK_THROW { return meta_calloc(nelem,size); }
00386 void cfree(void *ptr) CMK_THROW { meta_cfree(ptr); }
00387 void *realloc(void *ptr, size_t size) CMK_THROW { return meta_realloc(ptr,size); }
00388 CLINKAGE void *memalign(size_t align, size_t size) CMK_THROW { return meta_memalign(align,size); }
00389 CLINKAGE int posix_memalign(void **outptr, size_t align, size_t size) CMK_THROW { return meta_posix_memalign(outptr,align,size); }
00390 CLINKAGE void *aligned_alloc(size_t align, size_t size) CMK_THROW { return meta_aligned_alloc(align,size); }
00391 void *valloc(size_t size) CMK_THROW { return meta_valloc(size); }
00392 CLINKAGE void *pvalloc(size_t size) CMK_THROW { return meta_pvalloc(size); }
00393 #endif
00394
00395 #endif
00396
00397 #ifdef __GNUC__
00398 #pragma GCC diagnostic pop
00399 #endif
00400 #ifdef __INTEL_COMPILER
00401 #pragma warning pop
00402 #endif
00403
00404 static int skip_mallinfo = 0;
00405
00406 void CmiMemoryInit(char ** argv)
00407 {
00408 if(CmiMyRank() == 0) CmiMemoryIs_flag |= CMI_MEMORY_IS_OS;
00409 #if CMK_MEMORY_BUILD_OS_WRAPPED || CMK_MEMORY_BUILD_GNU_HOOKS
00410 CmiArgGroup("Converse","Memory module");
00411 meta_init(argv);
00412 CmiNodeAllBarrier();
00413 #endif
00414 CmiOutOfMemoryInit();
00415 if (getenv("MEMORYUSAGE_NO_MALLINFO")) skip_mallinfo = 1;
00416 }
00417
00418 CLINKAGE void *malloc_reentrant(size_t);
00419 CLINKAGE void free_reentrant(void *);
00420
00421 void *malloc_reentrant(size_t size) { return malloc(size); }
00422 void free_reentrant(void *mem) { free(mem); }
00423
00424
00425
00426
00427 #if ! CMK_HAS_SBRK
00428 namespace {
00429 int sbrk(int s) { return 0; }
00430 }
00431 #endif
00432
00433 #if CMK_C_INLINE
00434 #define INLINE inline
00435 #else
00436 #define INLINE
00437 #endif
00438
00439
00440 #if CMK_HAS_MSTATS
00441 #include <malloc/malloc.h>
00442 INLINE static CMK_TYPEDEF_UINT8 MemusageMstats(void){
00443 struct mstats ms = mstats();
00444 CMK_TYPEDEF_UINT8 memtotal = ms.bytes_used;
00445 return memtotal;
00446 }
00447 #else
00448 INLINE static CMK_TYPEDEF_UINT8 MemusageMstats(void) { return 0; }
00449 #endif
00450
00451 static int MemusageInited = 0;
00452 static uintptr_t MemusageInitSbrkval = 0;
00453 INLINE static CMK_TYPEDEF_UINT8 MemusageSbrk(void){
00454 uintptr_t newval;
00455 #ifdef __GNUC__
00456 #pragma GCC diagnostic push
00457 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
00458 #endif
00459 if(MemusageInited==0){
00460 MemusageInitSbrkval = (uintptr_t)sbrk(0);
00461 MemusageInited = 1;
00462 }
00463 newval = (uintptr_t)sbrk(0);
00464 #ifdef __GNUC__
00465 #pragma GCC diagnostic pop
00466 #endif
00467 return (newval - MemusageInitSbrkval);
00468 }
00469
00470 INLINE static CMK_TYPEDEF_UINT8 MemusageProcSelfStat(void){
00471 FILE *f;
00472 int i, ret;
00473 static int failed_once = 0;
00474 CMK_TYPEDEF_UINT8 vsz = 0;
00475
00476 if(failed_once) return 0;
00477
00478 f = fopen("/proc/self/stat", "r");
00479 if(!f) { failed_once = 1; return 0; }
00480 for(i=0; i<22; i++) ret = fscanf(f, "%*s");
00481 ret = fscanf(f, "%" PRIu64, &vsz);
00482 fclose(f);
00483 if(!vsz) failed_once=1;
00484 return vsz;
00485 }
00486
00487 #if ! CMK_HAS_MALLINFO || defined(CMK_MALLINFO_IS_BROKEN)
00488 INLINE static CMK_TYPEDEF_UINT8 MemusageMallinfo(void){ return 0;}
00489 #else
00490 #if CMK_HAS_MALLOC_H
00491 #include <malloc.h>
00492 #endif
00493 INLINE static CMK_TYPEDEF_UINT8 MemusageMallinfo(void){
00494
00495 if (skip_mallinfo) return 0;
00496 else {
00497 struct mallinfo mi;
00498 #if CMK_MEMORY_BUILD_OS_WRAPPED && !CMK_MEMORY_BUILD_GNU_HOOKS
00499 if (mm_mallinfo == NULL)
00500 initialize_memory_wrapper();
00501 mi = (*mm_mallinfo)();
00502 #else
00503 mi = mallinfo();
00504 #endif
00505 CMK_TYPEDEF_UINT8 memtotal = (CMK_TYPEDEF_UINT8) mi.uordblks;
00506 CMK_TYPEDEF_UINT8 memtotal2 = (CMK_TYPEDEF_UINT8) mi.usmblks;
00507 memtotal2 += (CMK_TYPEDEF_UINT8) mi.hblkhd;
00508
00509 #if !CMK_CRAYXE && !CMK_CRAYXC
00510 if(memtotal2 > memtotal) memtotal = memtotal2;
00511 #endif
00512 return memtotal;
00513 }
00514 }
00515 #endif
00516
00517 INLINE static CMK_TYPEDEF_UINT8 MemusagePS(void){
00518 #if ! CMK_HAS_POPEN
00519 return 0;
00520 #else
00521 char pscmd[100];
00522 CMK_TYPEDEF_UINT8 vsz=0;
00523 FILE *p;
00524 int ret;
00525 sprintf(pscmd, "/bin/ps -o vsz= -p %d", getpid());
00526 p = popen(pscmd, "r");
00527 if(p){
00528 ret = fscanf(p, "%" PRIu64, &vsz);
00529 pclose(p);
00530 }
00531 return (vsz * (CMK_TYPEDEF_UINT8)1024);
00532 #endif
00533 }
00534
00535 #if defined(_WIN32)
00536 #include <windows.h>
00537 #include <psapi.h>
00538
00539 INLINE static CMK_TYPEDEF_UINT8 MemusageWindows(void){
00540 PROCESS_MEMORY_COUNTERS pmc;
00541 if ( GetProcessMemoryInfo( GetCurrentProcess(), &pmc, sizeof(pmc)) )
00542 {
00543
00544 return pmc.PagefileUsage;
00545 }
00546 return 0;
00547 }
00548 #else
00549 static CMK_TYPEDEF_UINT8 MemusageWindows(void){
00550 return 0;
00551 }
00552 #endif
00553
00554 #if CMK_BLUEGENEQ
00555 #include <spi/include/kernel/memory.h>
00556 INLINE static CMK_TYPEDEF_UINT8 MemusageBGQ(void){
00557 uint64_t heapUsed;
00558 Kernel_GetMemorySize(KERNEL_MEMSIZE_HEAP, &heapUsed);
00559 return (CMK_TYPEDEF_UINT8)heapUsed;
00560 }
00561 #else
00562 static CMK_TYPEDEF_UINT8 MemusageBGQ(void){
00563 return 0;
00564 }
00565 #endif
00566
00567 typedef CMK_TYPEDEF_UINT8 (*CmiMemUsageFn)(void);
00568
00569
00570 struct CmiMemUsageStruct {
00571 CmiMemUsageFn fn;
00572 const char *name;
00573 } memtest_order[] = {
00574 {MemusageBGQ, "BlueGene/Q"},
00575 {MemusageWindows, "Windows"},
00576 {MemusageMstats, "Mstats"},
00577 {MemusageMallinfo, "Mallinfo"},
00578 {MemusageProcSelfStat, "/proc/self/stat"},
00579 {MemusageSbrk, "sbrk"},
00580 {MemusagePS, "ps"},
00581 };
00582
00583 CMK_TYPEDEF_UINT8 CmiMemoryUsage(void){
00584 int i;
00585 CMK_TYPEDEF_UINT8 memtotal = 0;
00586 for (i=0; i<sizeof(memtest_order)/sizeof(struct CmiMemUsageStruct); i++) {
00587 memtotal = memtest_order[i].fn();
00588 if (memtotal) break;
00589 }
00590 return memtotal;
00591 }
00592
00593 const char *CmiMemoryUsageReporter(void){
00594 int i;
00595 CMK_TYPEDEF_UINT8 memtotal = 0;
00596 const char *reporter = NULL;
00597 for (i=0; i<sizeof(memtest_order)/sizeof(struct CmiMemUsageStruct); i++) {
00598 memtotal = memtest_order[i].fn();
00599 reporter = memtest_order[i].name;
00600 if (memtotal) break;
00601 }
00602 return reporter;
00603 }
00604
00605
00606
00607 #if CMK_HAS_RUSAGE_THREAD
00608 #include <sys/resource.h>
00609 CMK_TYPEDEF_UINT8 CmiMaxMemoryUsageR(void) {
00610 struct rusage usage;
00611 getrusage(RUSAGE_SELF, &usage);
00612 return usage.ru_maxrss;
00613 }
00614 #else
00615 CMK_TYPEDEF_UINT8 CmiMaxMemoryUsageR(void) {
00616 return 0;
00617 }
00618 #endif
00619
00620 CMK_TYPEDEF_UINT8 CmiMaxMemoryUsage(void) { return 0; }
00621 void CmiResetMaxMemory(void) {}
00622 CMK_TYPEDEF_UINT8 CmiMinMemoryUsage(void) { return 0; }
00623 void CmiResetMinMemory(void) {}
00624
00625 #undef MEM_LOCK_AROUND
00626 #define MEM_LOCK_AROUND(code) code
00627
00628 #else
00629
00630
00631
00632
00633
00634 #if CMK_MEMORY_BUILD_GNU
00635 #define meta_malloc mm_malloc
00636 #define meta_free mm_free
00637 #define meta_calloc mm_calloc
00638 #define meta_cfree mm_cfree
00639 #define meta_realloc mm_realloc
00640 #define meta_memalign mm_memalign
00641 #define meta_posix_memalign mm_posix_memalign
00642 #define meta_aligned_alloc mm_aligned_alloc
00643 #define meta_valloc mm_valloc
00644 #define meta_pvalloc mm_pvalloc
00645
00646 #include "memory-gnu.C"
00647 static void meta_init(char **argv) {
00648 if (CmiMyRank()==0) CmiMemoryIs_flag |= CMI_MEMORY_IS_GNU;
00649 }
00650
00651 #endif
00652
00653 #define BEFORE_MALLOC_CALL
00654 #define AFTER_MALLOC_CALL
00655
00656 #if CMK_MEMORY_BUILD_VERBOSE
00657 #include "memory-verbose.C"
00658 #endif
00659
00660 #if CMK_MEMORY_BUILD_PARANOID
00661 #include "memory-paranoid.C"
00662 #endif
00663
00664 #if CMK_MEMORY_BUILD_LEAK
00665 #include "memory-leak.C"
00666 #endif
00667
00668 #if CMK_MEMORY_BUILD_ISOMALLOC
00669 #include "memory-isomalloc.C"
00670 #endif
00671
00672 #if CMK_MEMORY_BUILD_CHARMDEBUG
00673 #include "memory-charmdebug.C"
00674 #endif
00675
00676
00677 #if 0
00678
00679 #include "memory-gnu.C"
00680 static void meta_init(char **argv)
00681 {
00682
00683 }
00684 static void *meta_malloc(size_t size)
00685 {
00686 return mm_malloc(size);
00687 }
00688 static void meta_free(void *mem)
00689 {
00690 mm_free(mem);
00691 }
00692 static void *meta_calloc(size_t nelem, size_t size)
00693 {
00694 return mm_calloc(nelem,size);
00695 }
00696 static void meta_cfree(void *mem)
00697 {
00698 mm_cfree(m);
00699 }
00700 static void *meta_realloc(void *mem, size_t size)
00701 {
00702 return mm_realloc(mem,size);
00703 }
00704 static void *meta_memalign(size_t align, size_t size)
00705 {
00706 return mm_memalign(align,size);
00707 }
00708 static int meta_posix_memalign(void **outptr, size_t align, size_t size)
00709 {
00710 return mm_posix_memalign(outptr,align,size);
00711 }
00712 static void *meta_aligned_alloc(size_t align, size_t size)
00713 {
00714 return mm_aligned_alloc(align,size);
00715 }
00716 static void *meta_valloc(size_t size)
00717 {
00718 return mm_valloc(size);
00719 }
00720 static void *meta_pvalloc(size_t size)
00721 {
00722 return mm_pvalloc(size);
00723 }
00724 #endif
00725
00726
00727
00728
00729
00730 static int CmiMemoryInited = 0;
00731
00732 void CmiMemoryInit(char **argv)
00733 {
00734 CmiArgGroup("Converse","Memory module");
00735 meta_init(argv);
00736 CmiOutOfMemoryInit();
00737 if (CmiMyRank()==0) CmiMemoryInited = 1;
00738 CmiNodeAllBarrier();
00739 }
00740
00741
00742 #define MEM_LOCK_AROUND(code) \
00743 if (CmiMemoryInited && !CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC)) CmiMemLock(); \
00744 code; \
00745 if (CmiMemoryInited && !CmiMemoryIs(CMI_MEMORY_IS_ISOMALLOC)) CmiMemUnlock();
00746
00747
00748 #define REENTRANT_MEM_LOCK_AROUND(code) \
00749 int myRank=CmiMyRank(); \
00750 if (myRank!=rank_holding_CmiMemLock) { \
00751 CmiMemLock(); \
00752 rank_holding_CmiMemLock=myRank; \
00753 code; \
00754 rank_holding_CmiMemLock=-1; \
00755 CmiMemUnlock(); \
00756 } \
00757 else { \
00758 code; \
00759 }
00760
00761 void *malloc(size_t size) CMK_THROW
00762 {
00763 void *result;
00764 MEM_LOCK_AROUND( result = meta_malloc(size); )
00765 if (result==NULL) CmiOutOfMemory(size);
00766 return result;
00767 }
00768
00769 void free(void *mem) CMK_THROW
00770 {
00771 MEM_LOCK_AROUND( meta_free(mem); )
00772 }
00773
00774 void *calloc(size_t nelem, size_t size) CMK_THROW
00775 {
00776 void *result;
00777 MEM_LOCK_AROUND( result = meta_calloc(nelem, size); )
00778 if (result==NULL) CmiOutOfMemory(size);
00779 return result;
00780 }
00781
00782 void cfree(void *mem) CMK_THROW
00783 {
00784 MEM_LOCK_AROUND( meta_cfree(mem); )
00785 }
00786
00787 void *realloc(void *mem, size_t size) CMK_THROW
00788 {
00789 void *result;
00790 MEM_LOCK_AROUND( result = meta_realloc(mem, size); )
00791 return result;
00792 }
00793
00794 CLINKAGE void *memalign(size_t align, size_t size) CMK_THROW
00795 {
00796 void *result;
00797 MEM_LOCK_AROUND( result = meta_memalign(align, size); )
00798 if (result==NULL) CmiOutOfMemory(align*size);
00799 return result;
00800 }
00801
00802 CLINKAGE int posix_memalign (void **outptr, size_t align, size_t size) CMK_THROW
00803 {
00804 int result;
00805 MEM_LOCK_AROUND( result = meta_posix_memalign(outptr, align, size); )
00806 if (result!=0) CmiOutOfMemory(align*size);
00807 return result;
00808 }
00809
00810 CLINKAGE void *aligned_alloc(size_t align, size_t size) CMK_THROW
00811 {
00812 void *result;
00813 MEM_LOCK_AROUND( result = meta_aligned_alloc(align, size); )
00814 if (result==NULL) CmiOutOfMemory(align*size);
00815 return result;
00816 }
00817
00818 void *valloc(size_t size) CMK_THROW
00819 {
00820 void *result;
00821 MEM_LOCK_AROUND( result = meta_valloc(size); )
00822 if (result==NULL) CmiOutOfMemory(size);
00823 return result;
00824 }
00825
00826 void *pvalloc(size_t size) CMK_THROW
00827 {
00828 void *result;
00829 MEM_LOCK_AROUND( result = meta_pvalloc(size); )
00830 if (result==NULL) CmiOutOfMemory(size);
00831 return result;
00832 }
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842 CLINKAGE void *malloc_reentrant(size_t);
00843 CLINKAGE void free_reentrant(void *);
00844
00845 void *malloc_reentrant(size_t size) {
00846 void *result;
00847 REENTRANT_MEM_LOCK_AROUND( result = meta_malloc(size); )
00848 return result;
00849 }
00850
00851 void free_reentrant(void *mem)
00852 {
00853 REENTRANT_MEM_LOCK_AROUND( meta_free(mem); )
00854 }
00855
00857 CMK_TYPEDEF_UINT8 CmiMemoryUsage(void)
00858 {
00859 int i;
00860 struct malloc_arena* ar_ptr;
00861
00862 if(__malloc_initialized < 0)
00863 ptmalloc_init ();
00864
00865 size_t uordblks = 0;
00866
00867 for (i=0, ar_ptr = &main_arena;; ++i)
00868 {
00869 struct malloc_state* msp = (struct malloc_state *)arena_to_mspace(ar_ptr);
00870
00871 mstate ms = (mstate)msp;
00872 if (!ok_magic(ms)) {
00873 USAGE_ERROR_ACTION(ms,ms);
00874 }
00875 mstate m = ms;
00876
00877 if (!PREACTION(m)) {
00878 check_malloc_state(m);
00879 if (is_initialized(m)) {
00880 size_t mfree = m->topsize + TOP_FOOT_SIZE;
00881 msegmentptr s = &m->seg;
00882 while (s != 0) {
00883 mchunkptr q = align_as_chunk(s->base);
00884 while (segment_holds(s, q) &&
00885 q != m->top && q->head != FENCEPOST_HEAD) {
00886 size_t sz = chunksize(q);
00887 if (!cinuse(q)) {
00888 mfree += sz;
00889 }
00890 q = next_chunk(q);
00891 }
00892 s = s->next;
00893 }
00894
00895 uordblks += m->footprint - mfree;
00896 }
00897
00898 POSTACTION(m);
00899 }
00900
00901 ar_ptr = ar_ptr->next;
00902 if (ar_ptr == &main_arena)
00903 break;
00904 }
00905
00906 return uordblks;
00907 }
00908
00910 CMK_TYPEDEF_UINT8 CmiMaxMemoryUsage(void)
00911 {
00912 int i;
00913 struct malloc_arena* ar_ptr;
00914
00915 if(__malloc_initialized < 0)
00916 ptmalloc_init ();
00917
00918 size_t usmblks = 0;
00919
00920 for (i=0, ar_ptr = &main_arena;; ++i)
00921 {
00922 struct malloc_state* msp = (struct malloc_state *)arena_to_mspace(ar_ptr);
00923
00924 mstate ms = (mstate)msp;
00925 if (!ok_magic(ms)) {
00926 USAGE_ERROR_ACTION(ms,ms);
00927 }
00928 mstate m = ms;
00929
00930 if (!PREACTION(m)) {
00931 check_malloc_state(m);
00932 if (is_initialized(m)) {
00933 usmblks += m->max_footprint;
00934 }
00935
00936 POSTACTION(m);
00937 }
00938
00939 ar_ptr = ar_ptr->next;
00940 if (ar_ptr == &main_arena)
00941 break;
00942 }
00943
00944 return usmblks;
00945 }
00946
00948 void CmiResetMaxMemory(void) {
00949 }
00950
00951 CMK_TYPEDEF_UINT8 CmiMinMemoryUsage(void)
00952 {
00953 return 0;
00954 }
00955
00956 void CmiResetMinMemory(void) {
00957 }
00958
00959 #endif
00960
00961 #ifndef CMK_MEMORY_HAS_NOMIGRATE
00962
00963 CLINKAGE void *malloc_nomigrate(size_t);
00964 CLINKAGE void free_nomigrate(void *);
00965
00966 void *malloc_nomigrate(size_t size) { return malloc(size); }
00967 void free_nomigrate(void *mem) { free(mem); }
00968 #endif
00969
00970 #ifndef CMK_MEMORY_HAS_ISOMALLOC
00971 #include "memory-isomalloc.h"
00972
00973 CmiIsomallocBlockList *CmiIsomallocBlockListActivate(CmiIsomallocBlockList *l)
00974 {return l;}
00975 CmiIsomallocBlockList *CmiIsomallocBlockListCurrent(void){
00976 return NULL;
00977 }
00978 void CmiEnableIsomalloc(void) {}
00979 void CmiDisableIsomalloc(void) {}
00980 #endif
00981
00982 #ifndef CMI_MEMORY_ROUTINES
00983 void CmiMemoryMark(void) {}
00984 void CmiMemoryMarkBlock(void *blk) {}
00985 void CmiMemorySweep(const char *where) {}
00986 void CmiMemoryCheck(void) {}
00987 #endif
00988
00989 void memory_preallocate_hack(void)
00990 {
00991 #if CMK_MEMORY_PREALLOCATE_HACK
00992
00993
00994
00995
00996
00997 #define MEMORY_PREALLOCATE_MAX 4096
00998 void *ptrs[MEMORY_PREALLOCATE_MAX];
00999 int i,len=0;
01000 for (i=0;i<MEMORY_PREALLOCATE_MAX;i++) {
01001 ptrs[i] = mm_malloc(1024*1024);
01002 if (ptrs[i]==NULL) break;
01003 else len=i+1;
01004 }
01005
01006
01007 for (i=len-2;i>=0;i--) {
01008 mm_free(ptrs[i]);
01009 }
01010 #endif
01011 }
01012
01013 void CmiOutOfMemoryInit(void) {
01014 if (CmiMyRank() == 0) {
01015 #if CMK_MEMORY_PREALLOCATE_HACK
01016 memory_preallocate_hack();
01017 #endif
01018 MEM_LOCK_AROUND( memory_lifeRaft=(char *)mm_malloc(16384); )
01019 }
01020 }
01021
01022 #ifndef CMK_MEMORY_BUILD_CHARMDEBUG
01023
01024 void CpdSetInitializeMemory(int v) { }
01025 size_t cpd_memory_length(void *lenParam) { return 0; }
01026 void cpd_memory_pup(void *itemParam,pup_er p,CpdListItemsRequest *req) { }
01027 void cpd_memory_leak(void *itemParam,pup_er p,CpdListItemsRequest *req) { }
01028 void check_memory_leaks(LeakSearchInfo* i) { }
01029 size_t cpd_memory_getLength(void *lenParam) { return 0; }
01030 void cpd_memory_get(void *itemParam,pup_er p,CpdListItemsRequest *req) { }
01031 void CpdMemoryMarkClean(char *msg) { }
01032
01033
01034 void setProtection(char *mem, char *ptr, int len, int flag) { }
01035
01036 #ifdef setMemoryTypeChare
01037 #undef setMemoryTypeChare
01038 #endif
01039 void setMemoryTypeChare(void *ptr) { }
01040 #ifdef setMemoryTypeMessage
01041 #undef setMemoryTypeMessage
01042 #endif
01043 void setMemoryTypeMessage(void *ptr) { }
01044 void CpdSystemEnter(void) { }
01045 void CpdSystemExit(void) { }
01046
01047 void CpdResetMemory(void) { }
01048 void CpdCheckMemory(void) { }
01049
01050 int get_memory_allocated_user_total(void) { return 0; }
01051 void * MemoryToSlot(void *ptr) { return NULL; }
01052 int Slot_ChareOwner(void *s) { return 0; }
01053 int Slot_AllocatedSize(void *s) { return 0; }
01054 int Slot_StackTrace(void *s, void ***stack) { return 0; }
01055 #ifdef setMemoryChareIDFromPtr
01056 #undef setMemoryChareIDFromPtr
01057 #endif
01058 int setMemoryChareIDFromPtr(void *ptr) { return 0; }
01059 #ifdef setMemoryChareID
01060 #undef setMemoryChareID
01061 #endif
01062 void setMemoryChareID(int id) { }
01063 #ifdef setMemoryOwnedBy
01064 #undef setMemoryOwnedBy
01065 #endif
01066 void setMemoryOwnedBy(void *ptr, int id) { }
01067
01068 #endif
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 void* CmiMallocAligned(const size_t size, const unsigned int alignment) {
01079
01080 void* rtn = NULL;
01081 int tailPadding;
01082 unsigned short offset = 0;
01083
01084
01085 if (size <= 0 || alignment <= 0) return NULL;
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095 tailPadding = alignment - (size % alignment);
01096 if (tailPadding == alignment)
01097 tailPadding = 0;
01098
01099
01100 rtn = malloc(size + alignment + tailPadding);
01101
01102
01103 offset = (char)(((size_t)rtn) % alignment);
01104 offset = alignment - offset;
01105 if (offset == 0) offset = alignment;
01106
01107
01108 *((char*)rtn + offset - 1) = offset;
01109
01110
01111
01112 return (void*)((char*)rtn + offset);
01113 }
01114
01115 void CmiFreeAligned(void* ptr) {
01116
01117 char offset;
01118
01119
01120 if (ptr == NULL) return;
01121
01122
01123 offset = *((char*)ptr - 1);
01124
01125
01126 free ((void*)((char*)ptr - offset));
01127 }
01128
01129
01130
01131
01132
01133 #if (CMK_MEMORY_BUILD_OS && CMK_MEMORY_BUILD_OS_WRAPPED && !CMK_MEMORY_BUILD_GNU_HOOKS) || !CMK_MEMORY_BUILD_OS
01134
01135 #if !defined CMI_MEMORY_GNU || !defined _LIBC
01136 CLINKAGE void * __libc_memalign (size_t alignment, size_t bytes) { return memalign(alignment, bytes); }
01137
01138 #if CMK_EXPECTS_MORECORE
01139 CLINKAGE void * __default_morecore (ptrdiff_t) CMK_THROW;
01140 void *(*__morecore)(ptrdiff_t) = __default_morecore;
01141 #endif
01142 #endif
01143
01144 #if defined CMI_MEMORY_GNU && defined _LIBC
01145 CLINKAGE int mallopt (int param_number, int value) CMK_THROW { return __libc_mallopt(param_number, value); }
01146 #elif !defined CMI_MEMORY_GNU || defined _LIBC
01147 CLINKAGE int mallopt (int param_number, int value) CMK_THROW { return 1; }
01148 #endif
01149
01150 CLINKAGE void __malloc_fork_lock_parent (void) { }
01151 CLINKAGE void __malloc_fork_unlock_parent (void) { }
01152 CLINKAGE void __malloc_fork_unlock_child (void) { }
01153
01154 #if defined __APPLE__
01155
01156 char * strdup (const char *str)
01157 {
01158 const size_t length = strlen(str);
01159 const size_t bufsize = length + 1;
01160 char * const buf = (char *)malloc(bufsize);
01161
01162 if (buf == nullptr)
01163 return nullptr;
01164
01165 memcpy(buf, str, bufsize);
01166 return buf;
01167 }
01168 char * strndup (const char *str, size_t n)
01169 {
01170 const size_t length = strnlen(str, n);
01171 const size_t bufsize = length + 1;
01172 char * const buf = (char *)malloc(bufsize);
01173
01174 if (buf == nullptr)
01175 return nullptr;
01176
01177 memcpy(buf, str, length);
01178 buf[length] = '\0';
01179 return buf;
01180 }
01181 #endif
01182
01183 #endif
01184
01185