diff options
Diffstat (limited to 'src/common/host_memory.cpp')
| -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 703ddb4a4..ba22595e0 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #ifndef _GNU_SOURCE | 18 | #ifndef _GNU_SOURCE |
| 19 | #define _GNU_SOURCE | 19 | #define _GNU_SOURCE |
| 20 | #endif | 20 | #endif |
| 21 | #include <boost/icl/interval_set.hpp> | ||
| 21 | #include <fcntl.h> | 22 | #include <fcntl.h> |
| 22 | #include <sys/mman.h> | 23 | #include <sys/mman.h> |
| 23 | #include <unistd.h> | 24 | #include <unistd.h> |
| @@ -423,6 +424,7 @@ public: | |||
| 423 | madvise(virtual_base, virtual_size, MADV_HUGEPAGE); | 424 | madvise(virtual_base, virtual_size, MADV_HUGEPAGE); |
| 424 | #endif | 425 | #endif |
| 425 | 426 | ||
| 427 | placeholders.add({0, virtual_size}); | ||
| 426 | good = true; | 428 | good = true; |
| 427 | } | 429 | } |
| 428 | 430 | ||
| @@ -431,6 +433,10 @@ public: | |||
| 431 | } | 433 | } |
| 432 | 434 | ||
| 433 | void Map(size_t virtual_offset, size_t host_offset, size_t length) { | 435 | void Map(size_t virtual_offset, size_t host_offset, size_t length) { |
| 436 | { | ||
| 437 | std::scoped_lock lock{placeholder_mutex}; | ||
| 438 | placeholders.subtract({virtual_offset, virtual_offset + length}); | ||
| 439 | } | ||
| 434 | 440 | ||
| 435 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_READ | PROT_WRITE, | 441 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_READ | PROT_WRITE, |
| 436 | MAP_SHARED | MAP_FIXED, fd, host_offset); | 442 | MAP_SHARED | MAP_FIXED, fd, host_offset); |
| @@ -441,6 +447,19 @@ public: | |||
| 441 | // The method name is wrong. We're still talking about the virtual range. | 447 | // The method name is wrong. We're still talking about the virtual range. |
| 442 | // We don't want to unmap, we want to reserve this memory. | 448 | // We don't want to unmap, we want to reserve this memory. |
| 443 | 449 | ||
| 450 | { | ||
| 451 | std::scoped_lock lock{placeholder_mutex}; | ||
| 452 | auto it = placeholders.find({virtual_offset - 1, virtual_offset + length + 1}); | ||
| 453 | |||
| 454 | if (it != placeholders.end()) { | ||
| 455 | size_t prev_upper = virtual_offset + length; | ||
| 456 | virtual_offset = std::min(virtual_offset, it->lower()); | ||
| 457 | length = std::max(it->upper(), prev_upper) - virtual_offset; | ||
| 458 | } | ||
| 459 | |||
| 460 | placeholders.add({virtual_offset, virtual_offset + length}); | ||
| 461 | } | ||
| 462 | |||
| 444 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_NONE, | 463 | void* ret = mmap(virtual_base + virtual_offset, length, PROT_NONE, |
| 445 | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); | 464 | MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); |
| 446 | ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); | 465 | ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); |
| @@ -484,6 +503,9 @@ private: | |||
| 484 | } | 503 | } |
| 485 | 504 | ||
| 486 | int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create | 505 | int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create |
| 506 | |||
| 507 | boost::icl::interval_set<size_t> placeholders; ///< Mapped placeholders | ||
| 508 | std::mutex placeholder_mutex; ///< Mutex for placeholders | ||
| 487 | }; | 509 | }; |
| 488 | 510 | ||
| 489 | #else // ^^^ Linux ^^^ vvv Generic vvv | 511 | #else // ^^^ Linux ^^^ vvv Generic vvv |