rusage.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #if defined(__APPLE__) && defined(__MACH__)
  2. #include <mach/mach.h>
  3. #endif
  4. #ifdef _win_
  5. #include "winint.h"
  6. #include <psapi.h>
  7. #else
  8. #include <sys/resource.h>
  9. #endif
  10. #include <util/generic/yexception.h>
  11. #include "info.h"
  12. #include "rusage.h"
  13. #ifdef _win_
  14. TDuration FiletimeToDuration(const FILETIME& ft) {
  15. union {
  16. ui64 ft_scalar;
  17. FILETIME ft_struct;
  18. } nt_time;
  19. nt_time.ft_struct = ft;
  20. return TDuration::MicroSeconds(nt_time.ft_scalar / 10);
  21. }
  22. #endif
  23. size_t TRusage::GetCurrentRSS() {
  24. /*
  25. * Author: David Robert Nadeau
  26. * Site: http://NadeauSoftware.com/
  27. * License: Creative Commons Attribution 3.0 Unported License
  28. * http://creativecommons.org/licenses/by/3.0/deed.en_US
  29. */
  30. #if defined(_WIN32)
  31. /* Windows -------------------------------------------------- */
  32. PROCESS_MEMORY_COUNTERS info;
  33. GetProcessMemoryInfo(GetCurrentProcess(), &info, sizeof(info));
  34. return (size_t)info.WorkingSetSize;
  35. #elif defined(__APPLE__) && defined(__MACH__)
  36. /* OSX ------------------------------------------------------ */
  37. struct mach_task_basic_info info;
  38. mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
  39. if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO,
  40. (task_info_t)&info, &infoCount) != KERN_SUCCESS) {
  41. return (size_t)0L; /* Can't access? */
  42. }
  43. return (size_t)info.resident_size;
  44. #elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
  45. /* Linux ---------------------------------------------------- */
  46. long rss = 0L;
  47. FILE* fp = nullptr;
  48. if ((fp = fopen("/proc/self/statm", "r")) == nullptr) {
  49. return (size_t)0L; /* Can't open? */
  50. }
  51. if (fscanf(fp, "%*s%ld", &rss) != 1) {
  52. fclose(fp);
  53. return (size_t)0L; /* Can't read? */
  54. }
  55. fclose(fp);
  56. return (size_t)rss * (size_t)sysconf(_SC_PAGESIZE);
  57. #else
  58. /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
  59. return (size_t)0L; /* Unsupported. */
  60. #endif
  61. }
  62. void TRusage::Fill() {
  63. *this = TRusage();
  64. #ifdef _win_
  65. // copy-paste from PostgreSQL getrusage.c
  66. FILETIME starttime;
  67. FILETIME exittime;
  68. FILETIME kerneltime;
  69. FILETIME usertime;
  70. if (GetProcessTimes(GetCurrentProcess(), &starttime, &exittime, &kerneltime, &usertime) == 0) {
  71. ythrow TSystemError() << "GetProcessTimes failed";
  72. }
  73. Utime = FiletimeToDuration(usertime);
  74. Stime = FiletimeToDuration(kerneltime);
  75. PROCESS_MEMORY_COUNTERS pmc;
  76. if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)) == 0) {
  77. ythrow TSystemError() << "GetProcessMemoryInfo failed";
  78. }
  79. MaxRss = pmc.PeakWorkingSetSize;
  80. MajorPageFaults = pmc.PageFaultCount;
  81. #else
  82. struct rusage ru;
  83. int r = getrusage(RUSAGE_SELF, &ru);
  84. if (r < 0) {
  85. ythrow TSystemError() << "rusage failed";
  86. }
  87. #if defined(_darwin_)
  88. // see https://lists.apple.com/archives/darwin-kernel/2009/Mar/msg00005.html
  89. MaxRss = ru.ru_maxrss;
  90. #else
  91. MaxRss = ru.ru_maxrss * 1024LL;
  92. #endif
  93. MajorPageFaults = ru.ru_majflt;
  94. Utime = ru.ru_utime;
  95. Stime = ru.ru_stime;
  96. #endif
  97. }