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