stack_utils.cpp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. #include "stack_utils.h"
  2. #include <util/generic/scope.h>
  3. #include <util/system/yassert.h>
  4. #ifdef _linux_
  5. #include <sys/mman.h>
  6. #endif
  7. #include <cerrno>
  8. #include <cstdlib>
  9. #include <cstring>
  10. namespace NCoro::NStack {
  11. #ifdef _linux_
  12. bool GetAlignedMemory(size_t sizeInPages, char*& rawPtr, char*& alignedPtr) noexcept {
  13. Y_ASSERT(sizeInPages);
  14. void* ptr = nullptr;
  15. int error = posix_memalign(&ptr, PageSize, sizeInPages * PageSize);
  16. alignedPtr = rawPtr = (char*)ptr;
  17. return rawPtr && alignedPtr && !error;
  18. }
  19. #else
  20. bool GetAlignedMemory(size_t sizeInPages, char*& rawPtr, char*& alignedPtr) noexcept {
  21. Y_ASSERT(sizeInPages);
  22. rawPtr = (char*) malloc((sizeInPages + 1) * PageSize); // +1 in case result would be unaligned
  23. alignedPtr = (char*)( ((size_t)rawPtr + PageSize - 1) & ~PageSizeMask);
  24. return rawPtr && alignedPtr;
  25. }
  26. #endif
  27. #ifdef _linux_
  28. void ReleaseRss(char* alignedPtr, size_t numOfPages) noexcept {
  29. Y_ABORT_UNLESS( !((size_t)alignedPtr & PageSizeMask), "Not aligned pointer to release RSS memory");
  30. if (!numOfPages) {
  31. return;
  32. }
  33. if (auto res = madvise((void*) alignedPtr, numOfPages * PageSize, MADV_DONTNEED); res) {
  34. Y_ABORT_UNLESS(errno == EAGAIN || errno == ENOMEM, "Failed to release memory");
  35. }
  36. }
  37. #else
  38. void ReleaseRss(char*, size_t) noexcept {
  39. }
  40. #endif
  41. #ifdef _linux_
  42. size_t CountMapped(char* alignedPtr, size_t numOfPages) noexcept {
  43. Y_ABORT_UNLESS( !((size_t)alignedPtr & PageSizeMask) );
  44. Y_ASSERT(numOfPages);
  45. size_t result = 0;
  46. unsigned char* mappedPages = (unsigned char*) calloc(numOfPages, numOfPages);
  47. Y_ABORT_UNLESS(mappedPages);
  48. Y_DEFER {
  49. free(mappedPages);
  50. };
  51. if (!mincore((void*)alignedPtr, numOfPages * PageSize, mappedPages)) {
  52. for (size_t i = 0; i < numOfPages; ++i) {
  53. if (mappedPages[i] & 1) {
  54. ++result;
  55. }
  56. }
  57. } else {
  58. Y_ASSERT(false);
  59. return 0;
  60. }
  61. return result;
  62. }
  63. #else
  64. size_t CountMapped(char*, size_t) noexcept {
  65. return 0; // stub for Windows tests
  66. }
  67. #endif
  68. }