mlock.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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. if (!SetProcessWorkingSetSize(hndl, min + len, max + len))
  37. ythrow yexception() << LastSystemErrorText();
  38. if (!VirtualLock((LPVOID)addr, len))
  39. ythrow yexception() << LastSystemErrorText();
  40. #endif
  41. }
  42. void UnlockMemory(const void* addr, size_t len) {
  43. #if defined(_unix_)
  44. if (0 == len) {
  45. return;
  46. }
  47. Y_ASSERT(static_cast<ssize_t>(len) > 0);
  48. const size_t pageSize = NSystemInfo::GetPageSize();
  49. const char* begin = AlignDown(static_cast<const char*>(addr), pageSize);
  50. const char* end = AlignUp(static_cast<const char*>(addr) + len, pageSize);
  51. if (munlock(begin, end - begin)) {
  52. ythrow yexception() << LastSystemErrorText();
  53. }
  54. #elif defined(_win_)
  55. HANDLE hndl = GetCurrentProcess();
  56. SIZE_T min, max;
  57. if (!GetProcessWorkingSetSize(hndl, &min, &max))
  58. ythrow yexception() << LastSystemErrorText();
  59. if (!SetProcessWorkingSetSize(hndl, min - len, max - len))
  60. ythrow yexception() << LastSystemErrorText();
  61. if (!VirtualUnlock((LPVOID)addr, len))
  62. ythrow yexception() << LastSystemErrorText();
  63. #endif
  64. }
  65. void LockAllMemory(ELockAllMemoryFlags flags) {
  66. Y_UNUSED(flags);
  67. #if defined(_android_)
  68. // unimplemented
  69. #elif defined(_cygwin_)
  70. // unimplemented
  71. #elif defined(_unix_)
  72. int sys_flags = 0;
  73. if (flags & LockCurrentMemory) {
  74. sys_flags |= MCL_CURRENT;
  75. }
  76. if (flags & LockFutureMemory) {
  77. sys_flags |= MCL_FUTURE;
  78. }
  79. if (flags & LockMemoryOnFault) {
  80. sys_flags |= MCL_ONFAULT;
  81. }
  82. if (mlockall(sys_flags)) {
  83. ythrow yexception() << LastSystemErrorText();
  84. }
  85. #endif
  86. }
  87. void UnlockAllMemory() {
  88. #if defined(_cygwin_)
  89. // unimplemented
  90. #elif defined(_unix_)
  91. if (munlockall()) {
  92. ythrow yexception() << LastSystemErrorText();
  93. }
  94. #endif
  95. }