00001
00007 #include "memusage.h"
00008 #include "converse.h"
00009 #ifndef WIN32
00010 #include <stdio.h>
00011 #include <sys/types.h>
00012 #include <unistd.h>
00013 #else
00014 int sbrk(int) { return 0; }
00015 #endif
00016
00017 int memusageinit::initialized;
00018 unsigned long memusageinit::sbrkval;
00019
00020 memusageinit::memusageinit() {
00021 if ( initialized == 0 ) {
00022 sbrkval = (unsigned long) sbrk(0);
00023 initialized = 1;
00024 }
00025 }
00026
00027 unsigned long memusageinit::memusage_sbrk() {
00028 unsigned long newval = (unsigned long) sbrk(0);
00029 return ( newval - memusageinit::sbrkval );
00030 }
00031
00032
00033 #ifdef WIN32
00034 #define MEMUSAGE_USE_SBRK
00035 #endif
00036
00037 #ifdef _NO_MALLOC_H
00038 #define NO_MALLINFO
00039 #endif
00040
00041 #ifdef MEMUSAGE_USE_SBRK
00042 #define NO_MALLINFO
00043 #define NO_PS
00044 #endif
00045
00046
00047 #ifdef MEMUSAGE_USE_MSTATS
00048
00049 #include <malloc/malloc.h>
00050
00051 unsigned long memusage_mstats() {
00052 struct mstats ms = mstats();
00053 unsigned long memtotal = ms.bytes_used;
00054 return memtotal;
00055 }
00056
00057 #else
00058 inline unsigned long memusage_mstats() { return 0; }
00059 #endif
00060
00061
00062 #ifndef NO_MALLINFO
00063
00064 #include <malloc.h>
00065
00066 unsigned long memusage_mallinfo() {
00067 struct mallinfo mi = mallinfo();
00068
00069 unsigned long memtotal = (unsigned int) mi.uordblks;
00070 unsigned long memtotal2 = (unsigned int) mi.usmblks;
00071 memtotal2 += (unsigned int) mi.hblkhd;
00072 if ( memtotal2 > memtotal ) memtotal = memtotal2;
00073
00074
00075
00076 return memtotal;
00077 }
00078
00079 #else
00080 inline unsigned long memusage_mallinfo() { return 0; }
00081 #endif
00082
00083
00084 inline unsigned long memusage_ps() {
00085 #ifdef NO_PS
00086 return 0;
00087 #else
00088 char pscmd[100];
00089 #ifdef NAMD_CUDA
00090 sprintf(pscmd, "/bin/ps -o rss= -p %d", getpid());
00091 #else
00092 sprintf(pscmd, "/bin/ps -o vsz= -p %d", getpid());
00093 #endif
00094 unsigned long vsz = 0;
00095 FILE *p = popen(pscmd, "r");
00096 if ( p ) {
00097 fscanf(p, "%ld", &vsz);
00098 pclose(p);
00099 }
00100 return ( vsz * (unsigned long) 1024 );
00101 #endif
00102 }
00103
00104 #if CMK_BLUEGENEP
00105
00106
00107
00108 #include <malloc.h>
00109 inline long long memusage_bgp(){
00110 struct mallinfo m = mallinfo();
00111 return m.hblkhd + m.uordblks;
00112 }
00113 #endif
00114
00115 inline unsigned long memusage_proc_self_stat() {
00116 #ifdef NO_PS
00117 return 0;
00118 #else
00119 static int failed_once = 0;
00120 if ( failed_once ) return 0;
00121
00122 FILE *f = fopen("/proc/self/stat","r");
00123 if ( ! f ) { failed_once = 1; return 0; }
00124 for ( int i=0; i<22; ++i ) fscanf(f,"%*s");
00125 #ifdef NAMD_CUDA
00126
00127 fscanf(f,"%*s");
00128 #endif
00129 unsigned long vsz = 0;
00130 fscanf(f,"%lu",&vsz);
00131 fclose(f);
00132 #ifdef NAMD_CUDA
00133 vsz *= sysconf(_SC_PAGESIZE);
00134 #endif
00135 if ( ! vsz ) failed_once = 1;
00136
00137 return vsz;
00138 #endif
00139 }
00140
00141
00142 unsigned long memusage(const char **source) {
00143
00144 unsigned long memtotal = 0;
00145 const char* s = "ERROR";
00146
00147 if ( ! CmiMemoryIs(CMI_MEMORY_IS_OS) ) {
00148 memtotal = CmiMemoryUsage(); s = "CmiMemoryUsage";
00149 }
00150
00151 #if defined(WIN32) && !defined(__CYGWIN__) && CHARM_VERSION > 60102
00152 if ( ! memtotal ) {
00153 memtotal = CmiMemoryUsage(); s = "GetProcessMemoryInfo";
00154 }
00155 #endif
00156
00157 if ( ! memtotal ) {
00158 memtotal = memusage_proc_self_stat(); s = "/proc/self/stat";
00159 }
00160
00161 #if CMK_BLUEGENEP
00162 if( ! memtotal) { memtotal = memusage_bgp(); s="mallinfo on BG/P"; }
00163 #endif
00164
00165 if ( ! memtotal ) { memtotal = memusage_mstats(); s = "mstats"; }
00166
00167 if ( ! memtotal ) { memtotal = memusage_mallinfo(); s = "mallinfo"; }
00168
00169 if ( ! memtotal ) { memtotal = memusageinit::memusage_sbrk(); s = "sbrk"; }
00170
00171 if ( ! memtotal ) { memtotal = memusage_ps(); s = "ps"; }
00172
00173 if ( ! memtotal ) { memtotal = CmiMemoryUsage(); s = "CmiMemoryUsage"; }
00174
00175 if ( ! memtotal ) s = "nothing";
00176
00177 if ( source ) *source = s;
00178
00179 return memtotal;
00180
00181 }
00182