memusage.C

Go to the documentation of this file.
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   // unsigned long memtotal = mi.usmblks + mi.uordblks + mi.hblkhd;
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   // printf("mallinfo %d %d %d\n", mi.usmblks, mi.uordblks, mi.hblkhd);
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 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
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_BLUEGENEQ
00105 /* Report the memusage according to
00106  * https://wiki.alcf.anl.gov/parts/index.php/Blue_Gene/Q#CNK_Memory_Information
00107  */
00108 #include <spi/include/kernel/memory.h>
00109 inline long long memusage_bgq(){
00110     uint64_t heap;
00111     Kernel_GetMemorySize(KERNEL_MEMSIZE_HEAP, &heap);
00112     return heap;
00113 }
00114 #endif
00115 
00116 #if CMK_BLUEGENEP
00117 /* Report the memusage according to
00118  * http://www.alcf.anl.gov/resource-guides/determining-memory-use
00119  */
00120 #include <malloc.h>
00121 inline long long memusage_bgp(){
00122     struct mallinfo m = mallinfo();
00123     long long hblkhd = (unsigned int) m.hblkhd;
00124     long long uordblks = (unsigned int) m.uordblks;
00125     return hblkhd + uordblks;
00126 }
00127 #endif
00128 
00129 inline unsigned long memusage_proc_self_stat() {
00130 #ifdef NO_PS
00131   return 0;
00132 #else
00133   static int failed_once = 0;
00134   if ( failed_once ) return 0;  // no point in retrying
00135 
00136   FILE *f = fopen("/proc/self/stat","r");
00137   if ( ! f ) { failed_once = 1; return 0; }
00138   for ( int i=0; i<22; ++i ) fscanf(f,"%*s");
00139 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
00140   // skip vss, next value is rss in pages
00141   fscanf(f,"%*s");
00142 #endif
00143   unsigned long vsz = 0;  // should remain 0 on failure
00144   fscanf(f,"%lu",&vsz);
00145   fclose(f);
00146 #if defined(NAMD_CUDA) || defined(NAMD_MIC)
00147   vsz *= sysconf(_SC_PAGESIZE);
00148 #endif
00149   if ( ! vsz ) failed_once = 1;
00150   // printf("/proc/self/stat reports %d MB\n", vsz/(1024*1024));
00151   return vsz;
00152 #endif
00153 }
00154 
00155 
00156 unsigned long memusage(const char **source) {
00157 
00158   unsigned long memtotal = 0;
00159   const char* s = "ERROR";
00160 
00161   if ( ! CmiMemoryIs(CMI_MEMORY_IS_OS) ) {
00162     memtotal = CmiMemoryUsage();  s = "CmiMemoryUsage";
00163   }
00164 
00165 #if CMK_BLUEGENEQ
00166   if( ! memtotal) { memtotal = memusage_bgq(); s="Kernel_GetMemorySize on BG/Q"; }
00167 #endif
00168 
00169 #if CMK_BLUEGENEP
00170   if( ! memtotal) { memtotal = memusage_bgp(); s="mallinfo on BG/P"; }
00171 #endif
00172 
00173 #if defined(WIN32) && !defined(__CYGWIN__)
00174   if ( ! memtotal ) {
00175     memtotal = CmiMemoryUsage();  s = "GetProcessMemoryInfo";
00176   }
00177 #endif
00178 
00179   if ( ! memtotal ) {
00180     memtotal = memusage_proc_self_stat();  s = "/proc/self/stat";
00181   }
00182 
00183   if ( ! memtotal ) { memtotal = memusage_mstats(); s = "mstats"; }
00184 
00185   if ( ! memtotal ) { memtotal = memusage_mallinfo(); s = "mallinfo"; }
00186 
00187   if ( ! memtotal ) { memtotal = memusageinit::memusage_sbrk(); s = "sbrk"; }
00188 
00189   if ( ! memtotal ) { memtotal = memusage_ps(); s = "ps"; }
00190 
00191   if ( ! memtotal ) { memtotal = CmiMemoryUsage();  s = "CmiMemoryUsage"; }
00192 
00193   if ( ! memtotal ) s = "nothing";
00194 
00195   if ( source ) *source = s;
00196 
00197   return memtotal;
00198 
00199 }
00200 

Generated on Sat Sep 23 01:17:14 2017 for NAMD by  doxygen 1.4.7