memtrack.hpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #ifndef memtrack_hpp
  2. #define memtrack_hpp
  3. /*
  4. * Author: David Robert Nadeau
  5. * Site: http://NadeauSoftware.com/
  6. * License: Creative Commons Attribution 3.0 Unported License
  7. * http://creativecommons.org/licenses/by/3.0/deed.en_US
  8. */
  9. #if defined(_WIN32)
  10. #include <windows.h>
  11. #include <psapi.h>
  12. #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
  13. #include <unistd.h>
  14. #include <sys/resource.h>
  15. #if defined(__APPLE__) && defined(__MACH__)
  16. #include <mach/mach.h>
  17. #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
  18. #include <fcntl.h>
  19. #include <procfs.h>
  20. #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
  21. #include <stdio.h>
  22. #endif
  23. #else
  24. #error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
  25. #endif
  26. namespace fv{
  27. /**
  28. * Returns the peak (maximum so far) resident set size (physical
  29. * memory use) measured in bytes, or zero if the value cannot be
  30. * determined on this OS.
  31. */
  32. size_t getPeakRSS( )
  33. {
  34. #if defined(_WIN32)
  35. /* Windows -------------------------------------------------- */
  36. PROCESS_MEMORY_COUNTERS info;
  37. GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
  38. return (size_t)info.PeakWorkingSetSize;
  39. #elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
  40. /* AIX and Solaris ------------------------------------------ */
  41. struct psinfo psinfo;
  42. int fd = -1;
  43. if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
  44. return (size_t)0L; /* Can't open? */
  45. if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
  46. {
  47. close( fd );
  48. return (size_t)0L; /* Can't read? */
  49. }
  50. close( fd );
  51. return (size_t)(psinfo.pr_rssize * 1024L);
  52. #elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
  53. /* BSD, Linux, and OSX -------------------------------------- */
  54. struct rusage rusage;
  55. getrusage( RUSAGE_SELF, &rusage );
  56. #if defined(__APPLE__) && defined(__MACH__)
  57. return (size_t)rusage.ru_maxrss;
  58. #else
  59. return (size_t)(rusage.ru_maxrss * 1024L);
  60. #endif
  61. #else
  62. /* Unknown OS ----------------------------------------------- */
  63. return (size_t)0L; /* Unsupported. */
  64. #endif
  65. }
  66. /**
  67. * Returns the current resident set size (physical memory use) measured
  68. * in bytes, or zero if the value cannot be determined on this OS.
  69. */
  70. size_t getCurrentRSS( )
  71. {
  72. #if defined(_WIN32)
  73. /* Windows -------------------------------------------------- */
  74. PROCESS_MEMORY_COUNTERS info;
  75. GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
  76. return (size_t)info.WorkingSetSize;
  77. #elif defined(__APPLE__) && defined(__MACH__)
  78. /* OSX ------------------------------------------------------ */
  79. struct mach_task_basic_info info;
  80. mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
  81. if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
  82. (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
  83. return (size_t)0L; /* Can't access? */
  84. return (size_t)info.resident_size;
  85. #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
  86. /* Linux ---------------------------------------------------- */
  87. long rss = 0L;
  88. FILE* fp = NULL;
  89. if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
  90. return (size_t)0L; /* Can't open? */
  91. if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
  92. {
  93. fclose( fp );
  94. return (size_t)0L; /* Can't read? */
  95. }
  96. fclose( fp );
  97. return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
  98. #else
  99. /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
  100. return (size_t)0L; /* Unsupported. */
  101. #endif
  102. }
  103. } // fv
  104. #endif // memtrack_hpp