diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/host_memory.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 8e4f1f97a..01457d8c6 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #ifndef _GNU_SOURCE | 14 | #ifndef _GNU_SOURCE |
| 15 | #define _GNU_SOURCE | 15 | #define _GNU_SOURCE |
| 16 | #endif | 16 | #endif |
| 17 | #include <boost/icl/interval_set.hpp> | ||
| 17 | #include <fcntl.h> | 18 | #include <fcntl.h> |
| 18 | #include <sys/mman.h> | 19 | #include <sys/mman.h> |
| 19 | #include <unistd.h> | 20 | #include <unistd.h> |
| @@ -415,6 +416,7 @@ public: | |||
| 415 | madvise(virtual_base, virtual_size, MADV_HUGEPAGE); | 416 | madvise(virtual_base, virtual_size, MADV_HUGEPAGE); |
| 416 | #endif | 417 | #endif |
| 417 | 418 | ||
| 419 | placeholders.add({0, virtual_size}); | ||
| 418 | good = true; | 420 | good = true; |
| 419 | } | 421 | } |
| 420 | 422 | ||
| @@ -423,6 +425,10 @@ public: | |||
| 423 | } | 425 | } |
| 424 | 426 | ||
| 425 | void Map(size_t virtual_offset, size_t host_offset, size_t length) { | 427 | void Map(size_t virtual_offset, size_t host_offset, size_t length) { |
| 428 | { | ||
| 429 | std::scoped_lock lock{placeholder_mutex}; | ||
| 430 | placeholders.subtract({virtual_offset, virtual_offset + length}); | ||
| 431 | } | ||
| 426 | 432 | ||
| 427 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_READ | PROT_WRITE, | 433 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_READ | PROT_WRITE, |
| 428 | MAP_SHARED | MAP_FIXED, fd, host_offset); | 434 | MAP_SHARED | MAP_FIXED, fd, host_offset); |
| @@ -433,6 +439,19 @@ public: | |||
| 433 | // The method name is wrong. We're still talking about the virtual range. | 439 | // The method name is wrong. We're still talking about the virtual range. |
| 434 | // We don't want to unmap, we want to reserve this memory. | 440 | // We don't want to unmap, we want to reserve this memory. |
| 435 | 441 | ||
| 442 | { | ||
| 443 | std::scoped_lock lock{placeholder_mutex}; | ||
| 444 | auto it = placeholders.find({virtual_offset - 1, virtual_offset + length + 1}); | ||
| 445 | |||
| 446 | if (it != placeholders.end()) { | ||
| 447 | size_t prev_upper = virtual_offset + length; | ||
| 448 | virtual_offset = std::min(virtual_offset, it->lower()); | ||
| 449 | length = std::max(it->upper(), prev_upper) - virtual_offset; | ||
| 450 | } | ||
| 451 | |||
| 452 | placeholders.add({virtual_offset, virtual_offset + length}); | ||
| 453 | } | ||
| 454 | |||
| 436 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_NONE, | 455 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_NONE, |
| 437 | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); | 456 | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); |
| 438 | ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); | 457 | ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); |
| @@ -476,6 +495,9 @@ private: | |||
| 476 | } | 495 | } |
| 477 | 496 | ||
| 478 | int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create | 497 | int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create |
| 498 | |||
| 499 | boost::icl::interval_set<size_t> placeholders; ///< Mapped placeholders | ||
| 500 | std::mutex placeholder_mutex; ///< Mutex for placeholders | ||
| 479 | }; | 501 | }; |
| 480 | 502 | ||
| 481 | #else // ^^^ Linux ^^^ vvv Generic vvv | 503 | #else // ^^^ Linux ^^^ vvv Generic vvv |