summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/host_memory.cpp22
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