Port the general way of getting memory usage information from NAMD into Charm++ when...
[charm.git] / src / conv-core / memory.c
index 3157d97458c235a447d5980f2ce55a2e91b6ee18..748389bfcbe77cdc574ff205a9aa950d0f0ff803 100644 (file)
@@ -284,7 +284,122 @@ void CmiMemoryInit(argv)
 void *malloc_reentrant(size_t size) { return malloc(size); }
 void free_reentrant(void *mem) { free(mem); }
 
-CMK_TYPEDEF_UINT8 CmiMemoryUsage() { return 0; }
+/******Start of a general way to get memory usage information*****/
+/*CMK_TYPEDEF_UINT8 CmiMemoryUsage() { return 0; }*/
+#ifdef WIN32
+#define MEMUSAGE_USE_SBRK
+int sbrk(int) { return 0; }
+#endif
+
+#ifdef NO_MALLOC_H
+#define NO_MALLINFO
+#endif
+
+#ifdef MEMUSAGE_USE_SBRK
+#define NO_MALLINFO
+#define NO_PS
+#endif
+
+#ifdef MEMUSAGE_USE_MSTATS
+#include <malloc/malloc.h>
+#if CMK_C_INLINE
+inline
+#endif
+static CMK_TYPEDEF_UINT8 MemusageMstats(){
+       struct mstats ms = mstats();
+       CMK_TYPEDEF_UINT8 memtotal = ms.bytes_used;
+       return memtotal;
+}
+#else
+#if CMK_C_INLINE
+inline
+#endif
+static CMK_TYPEDEF_UINT8 MemusageMstats() { return 0; }
+#endif
+
+static int MemusageInited = 0;
+static CMK_TYPEDEF_UINT8 MemusageInitSbrkval = 0;
+#if CMK_C_INLINE
+inline
+#endif
+static CMK_TYPEDEF_UINT8 MemusageSbrk(){
+       CMK_TYPEDEF_UINT8 newval;
+       if(MemusageInited==0){
+               MemusageInitSbrkval = (CMK_TYPEDEF_UINT8)sbrk(0);
+               MemusageInited = 1;
+       }
+       newval = (CMK_TYPEDEF_UINT8)sbrk(0);
+       return (newval - MemusageInitSbrkval);
+}
+
+#if CMK_C_INLINE
+inline
+#endif
+static CMK_TYPEDEF_UINT8 MemusageProcSelfStat(){
+    static int failed_once = 0;
+    if(failed_once) return 0; /* no point in retrying */
+    
+    FILE *f = fopen("/proc/self/stat", "r");
+    if(!f) { failed_once = 1; return 0; }
+       int i;
+    for(i=0; i<22; i++) fscanf(f, "%*s");
+    CMK_TYPEDEF_UINT8 vsz = 0; /* should remain 0 on failure */
+    fscanf(f, "%lu", &vsz);
+    fclose(f);
+    if(!vsz) failed_once=1;
+    return vsz;
+}
+
+#ifdef NO_MALLINFO
+#if CMK_C_INLINE
+inline
+#endif
+static CMK_TYPEDEF_UINT8 MemusageMallinfo(){ return 0;}        
+#else
+#include <malloc.h>
+#if CMK_C_INLINE
+inline
+#endif
+static CMK_TYPEDEF_UINT8 MemusageMallinfo(){
+    struct mallinfo mi = mallinfo();
+    CMK_TYPEDEF_UINT8 memtotal = (CMK_TYPEDEF_UINT8) mi.uordblks;
+    CMK_TYPEDEF_UINT8 memtotal2 = (CMK_TYPEDEF_UINT8) mi.usmblks;
+    memtotal2 += (CMK_TYPEDEF_UINT8) mi.hblkhd;
+    if(memtotal2 > memtotal) memtotal = memtotal2;
+    return memtotal;
+}
+#endif
+
+#if CMK_C_INLINE
+inline
+#endif
+static CMK_TYPEDEF_UINT8 MemusagePS(){
+#ifdef NO_PS
+       return 0;
+#else  
+    char pscmd[100];
+    CMK_TYPEDEF_UINT8 vsz=0;
+    sprintf(pscmd, "/bin/ps -o vsz= -p %d", getpid());
+    FILE *p = popen(pscmd, "r");
+    if(p){
+       fscanf(p, "%ld", &vsz);
+       pclose(p);
+    }
+    return (vsz * (CMK_TYPEDEF_UINT8)1024);
+#endif 
+}
+
+CMK_TYPEDEF_UINT8 CmiMemoryUsage(){
+    CMK_TYPEDEF_UINT8 memtotal = 0;
+    memtotal = MemusageProcSelfStat();
+       if(!memtotal) memtotal = MemusageMstats();
+    if(!memtotal) memtotal = MemusageMallinfo();
+    if(!memtotal) memtotal = MemusageSbrk();
+       if(!memtotal) memtotal = MemusagePS();
+       return memtotal;
+}
+/******End of a general way to get memory usage information*****/
+
 CMK_TYPEDEF_UINT8 CmiMaxMemoryUsage() { return 0; }
 void CmiResetMaxMemory() {}
 CMK_TYPEDEF_UINT8 CmiMinMemoryUsage() { return 0; }