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.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index 611c7d1a3..ba22595e0 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -11,9 +11,14 @@
11 11
12#elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv 12#elif defined(__linux__) || defined(__FreeBSD__) // ^^^ Windows ^^^ vvv Linux vvv
13 13
14#ifdef ANDROID
15#include <android/sharedmem.h>
16#endif
17
14#ifndef _GNU_SOURCE 18#ifndef _GNU_SOURCE
15#define _GNU_SOURCE 19#define _GNU_SOURCE
16#endif 20#endif
21#include <boost/icl/interval_set.hpp>
17#include <fcntl.h> 22#include <fcntl.h>
18#include <sys/mman.h> 23#include <sys/mman.h>
19#include <unistd.h> 24#include <unistd.h>
@@ -322,7 +327,7 @@ private:
322 } 327 }
323 328
324 /// Return true when a given memory region is a "nieche" and the placeholders don't have to be 329 /// Return true when a given memory region is a "nieche" and the placeholders don't have to be
325 /// splitted. 330 /// split.
326 bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const { 331 bool IsNiechePlaceholder(size_t virtual_offset, size_t length) const {
327 const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length}); 332 const auto it = placeholders.upper_bound({virtual_offset, virtual_offset + length});
328 if (it != placeholders.end() && it->lower() == virtual_offset + length) { 333 if (it != placeholders.end() && it->lower() == virtual_offset + length) {
@@ -366,17 +371,20 @@ public:
366 } 371 }
367 372
368 // Backing memory initialization 373 // Backing memory initialization
369#if defined(__FreeBSD__) && __FreeBSD__ < 13 374#ifdef ANDROID
375 fd = ASharedMemory_create("HostMemory", backing_size);
376#elif defined(__FreeBSD__) && __FreeBSD__ < 13
370 // XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30 377 // XXX Drop after FreeBSD 12.* reaches EOL on 2024-06-30
371 fd = shm_open(SHM_ANON, O_RDWR, 0600); 378 fd = shm_open(SHM_ANON, O_RDWR, 0600);
372#else 379#else
373 fd = memfd_create("HostMemory", 0); 380 fd = memfd_create("HostMemory", 0);
374#endif 381#endif
375 if (fd == -1) { 382 if (fd < 0) {
376 LOG_CRITICAL(HW_Memory, "memfd_create failed: {}", strerror(errno)); 383 LOG_CRITICAL(HW_Memory, "memfd_create failed: {}", strerror(errno));
377 throw std::bad_alloc{}; 384 throw std::bad_alloc{};
378 } 385 }
379 386
387#ifndef ANDROID
380 // Defined to extend the file with zeros 388 // Defined to extend the file with zeros
381 int ret = ftruncate(fd, backing_size); 389 int ret = ftruncate(fd, backing_size);
382 if (ret != 0) { 390 if (ret != 0) {
@@ -384,6 +392,7 @@ public:
384 strerror(errno)); 392 strerror(errno));
385 throw std::bad_alloc{}; 393 throw std::bad_alloc{};
386 } 394 }
395#endif
387 396
388 backing_base = static_cast<u8*>( 397 backing_base = static_cast<u8*>(
389 mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); 398 mmap(nullptr, backing_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
@@ -415,6 +424,7 @@ public:
415 madvise(virtual_base, virtual_size, MADV_HUGEPAGE); 424 madvise(virtual_base, virtual_size, MADV_HUGEPAGE);
416#endif 425#endif
417 426
427 placeholders.add({0, virtual_size});
418 good = true; 428 good = true;
419 } 429 }
420 430
@@ -423,6 +433,10 @@ public:
423 } 433 }
424 434
425 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 }
426 440
427 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,
428 MAP_SHARED | MAP_FIXED, fd, host_offset); 442 MAP_SHARED | MAP_FIXED, fd, host_offset);
@@ -433,6 +447,19 @@ public:
433 // 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.
434 // 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.
435 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
436 void* ret = mmap(virtual_base + virtual_offset, length, PROT_NONE, 463 void* ret = mmap(virtual_base + virtual_offset, length, PROT_NONE,
437 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); 464 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
438 ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno)); 465 ASSERT_MSG(ret != MAP_FAILED, "mmap failed: {}", strerror(errno));
@@ -476,6 +503,9 @@ private:
476 } 503 }
477 504
478 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
479}; 509};
480 510
481#else // ^^^ Linux ^^^ vvv Generic vvv 511#else // ^^^ Linux ^^^ vvv Generic vvv
@@ -484,7 +514,7 @@ class HostMemory::Impl {
484public: 514public:
485 explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) { 515 explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) {
486 // This is just a place holder. 516 // This is just a place holder.
487 // Please implement fastmem in a propper way on your platform. 517 // Please implement fastmem in a proper way on your platform.
488 throw std::bad_alloc{}; 518 throw std::bad_alloc{};
489 } 519 }
490 520