mlock_linux.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include "mlock.h"
  2. #include <stdio.h>
  3. #include <sys/mman.h>
  4. #include <stdint.h>
  5. #include <inttypes.h>
  6. namespace NYT {
  7. ////////////////////////////////////////////////////////////////////////////////
  8. void PopulateFile(void* ptr, size_t size)
  9. {
  10. constexpr size_t PageSize = 4096;
  11. auto* begin = static_cast<volatile char*>(ptr);
  12. for (auto* current = begin; current < begin + size; current += PageSize) {
  13. *current;
  14. }
  15. }
  16. bool MlockFileMappings(bool populate)
  17. {
  18. auto* file = ::fopen("/proc/self/maps", "r");
  19. if (!file) {
  20. return false;
  21. }
  22. // Each line of /proc/<pid>/smaps has the following format:
  23. // address perms offset dev inode path
  24. // E.g.
  25. // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm
  26. bool failed = false;
  27. while (true) {
  28. char line[1024];
  29. if (!fgets(line, sizeof(line), file)) {
  30. break;
  31. }
  32. char addressStr[64];
  33. char permsStr[64];
  34. char offsetStr[64];
  35. char devStr[64];
  36. int inode;
  37. if (sscanf(line, "%s %s %s %s %d",
  38. addressStr,
  39. permsStr,
  40. offsetStr,
  41. devStr,
  42. &inode) != 5)
  43. {
  44. continue;
  45. }
  46. if (inode == 0) {
  47. continue;
  48. }
  49. if (permsStr[0] != 'r') {
  50. continue;
  51. }
  52. uintptr_t startAddress;
  53. uintptr_t endAddress;
  54. if (sscanf(addressStr, "%" PRIx64 "-%" PRIx64,
  55. &startAddress,
  56. &endAddress) != 2)
  57. {
  58. continue;
  59. }
  60. if (::mlock(reinterpret_cast<const void*>(startAddress), endAddress - startAddress) != 0) {
  61. failed = true;
  62. continue;
  63. }
  64. if (populate) {
  65. PopulateFile(reinterpret_cast<void*>(startAddress), endAddress - startAddress);
  66. }
  67. }
  68. ::fclose(file);
  69. return !failed;
  70. }
  71. ////////////////////////////////////////////////////////////////////////////////
  72. } // namespace NYT