mlock.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #include <util/generic/yexception.h>
  2. #include "align.h"
  3. #include "error.h"
  4. #include "info.h"
  5. #include "mlock.h"
  6. #if defined(_unix_)
  7. #include <sys/mman.h>
  8. #if !defined(MCL_ONFAULT) && defined(MCL_FUTURE) // Old glibc.
  9. #define MCL_ONFAULT (MCL_FUTURE << 1)
  10. #endif
  11. #if defined(_android_)
  12. #include <sys/syscall.h>
  13. #define munlockall() syscall(__NR_munlockall)
  14. #endif
  15. #else
  16. #include "winint.h"
  17. #endif
  18. #include <limits>
  19. void LockMemory(const void* addr, size_t len) {
  20. #if defined(_unix_)
  21. if (0 == len) {
  22. return;
  23. }
  24. Y_ASSERT(static_cast<ssize_t>(len) > 0);
  25. const size_t pageSize = NSystemInfo::GetPageSize();
  26. const char* begin = AlignDown(static_cast<const char*>(addr), pageSize);
  27. const char* end = AlignUp(static_cast<const char*>(addr) + len, pageSize);
  28. if (mlock(begin, end - begin)) {
  29. ythrow yexception() << LastSystemErrorText();
  30. }
  31. #elif defined(_win_)
  32. HANDLE hndl = GetCurrentProcess();
  33. SIZE_T min, max;
  34. if (!GetProcessWorkingSetSize(hndl, &min, &max)) {
  35. ythrow yexception() << LastSystemErrorText();
  36. }
  37. if (!SetProcessWorkingSetSize(hndl, min + len, max + len)) {
  38. ythrow yexception() << LastSystemErrorText();
  39. }
  40. if (!VirtualLock((LPVOID)addr, len)) {
  41. ythrow yexception() << LastSystemErrorText();
  42. }
  43. #endif
  44. }
  45. void UnlockMemory(const void* addr, size_t len) {
  46. #if defined(_unix_)
  47. if (0 == len) {
  48. return;
  49. }
  50. Y_ASSERT(static_cast<ssize_t>(len) > 0);
  51. const size_t pageSize = NSystemInfo::GetPageSize();
  52. const char* begin = AlignDown(static_cast<const char*>(addr), pageSize);
  53. const char* end = AlignUp(static_cast<const char*>(addr) + len, pageSize);
  54. if (munlock(begin, end - begin)) {
  55. ythrow yexception() << LastSystemErrorText();
  56. }
  57. #elif defined(_win_)
  58. HANDLE hndl = GetCurrentProcess();
  59. SIZE_T min, max;
  60. if (!GetProcessWorkingSetSize(hndl, &min, &max)) {
  61. ythrow yexception() << LastSystemErrorText();
  62. }
  63. if (!SetProcessWorkingSetSize(hndl, min - len, max - len)) {
  64. ythrow yexception() << LastSystemErrorText();
  65. }
  66. if (!VirtualUnlock((LPVOID)addr, len)) {
  67. ythrow yexception() << LastSystemErrorText();
  68. }
  69. #endif
  70. }
  71. void LockAllMemory(ELockAllMemoryFlags flags) {
  72. Y_UNUSED(flags);
  73. #if defined(_android_)
  74. // unimplemented
  75. #elif defined(_cygwin_)
  76. // unimplemented
  77. #elif defined(_unix_)
  78. int sys_flags = 0;
  79. if (flags & LockCurrentMemory) {
  80. sys_flags |= MCL_CURRENT;
  81. }
  82. if (flags & LockFutureMemory) {
  83. sys_flags |= MCL_FUTURE;
  84. }
  85. if (flags & LockMemoryOnFault) {
  86. sys_flags |= MCL_ONFAULT;
  87. }
  88. if (mlockall(sys_flags)) {
  89. ythrow yexception() << LastSystemErrorText();
  90. }
  91. #endif
  92. }
  93. void UnlockAllMemory() {
  94. #if defined(_cygwin_)
  95. // unimplemented
  96. #elif defined(_unix_)
  97. if (munlockall()) {
  98. ythrow yexception() << LastSystemErrorText();
  99. }
  100. #endif
  101. }