25#ifndef JOIN_CORE_MEMORY_HPP
26#define JOIN_CORE_MEMORY_HPP
33#include <system_error>
59 template <
typename Backend,
size_t Capacity,
typename SyncPolicy>
62 template <
typename Backend,
size_t Count,
size_t... Sizes>
66 template <
typename Backend,
template <
typename,
typename>
class SyncPolicy>
69 template <
typename,
typename>
72 template <
typename,
typename>
75 template <
typename,
typename>
84 long size = ::sysconf (_SC_PAGESIZE);
85 return (size > 0) ?
static_cast<uint64_t
> (size) : 4096;
94 static const uint64_t size = [] () {
96 int fd = ::memfd_create (
"hugepage", MFD_HUGETLB | MFD_CLOEXEC);
100 if (::fstat (fd, &st) == 0)
102 bytes =
static_cast<uint64_t
> (st.st_blksize);
120 inline int mbind (
void* ptr,
size_t size,
int numa)
noexcept
122 if (ptr ==
nullptr || numa < 0 || numa > (
static_cast<int> (
sizeof (
unsigned long) * 8) - 1))
128 unsigned long mask = (1UL << numa);
129 if (::mbind (ptr, size, MPOL_BIND, &mask,
sizeof (mask) * 8, MPOL_MF_STRICT | MPOL_MF_MOVE) == -1)
131 lastError = std::error_code (errno, std::generic_category ());
145 inline int mlock (
void* ptr,
size_t size)
noexcept
156 lastError = std::error_code (errno, std::generic_category ());
170 template <
size_t Capacity,
typename SyncPolicy = BumpAtomic>
184 : _ptr (((size != 0) && (size <= static_cast<uint64_t> (
std::numeric_limits<ptrdiff_t>::max ())))
190 throw std::bad_alloc ();
214 , _size (other._size)
216 other._ptr =
nullptr;
232 other._ptr =
nullptr;
252 return _ptr !=
nullptr;
262 const void*
get (uint64_t offset = 0)
const
266 throw std::runtime_error (
"memory not mapped");
271 throw std::out_of_range (
"offset out of bounds");
274 return static_cast<const char*
> (_ptr) + offset;
284 void*
get (uint64_t offset = 0)
288 throw std::runtime_error (
"memory not mapped");
293 throw std::out_of_range (
"offset out of bounds");
296 return static_cast<char*
> (_ptr) + offset;
303 void cleanup () noexcept
311 void* _ptr =
nullptr;
323 template <
size_t Capacity,
typename SyncPolicy = BumpAtomic>
326 template <
size_t Count,
size_t... Sizes>
346 _size = (size + page - 1) & ~(page - 1);
368 : _size (other._size)
372 other._ptr =
nullptr;
388 other._ptr =
nullptr;
407 return _ptr !=
nullptr;
417 const void*
get (uint64_t offset = 0)
const
421 throw std::runtime_error (
"memory not mapped");
426 throw std::out_of_range (
"offset out of bounds");
429 return static_cast<const char*
> (_ptr) + offset;
439 void*
get (uint64_t offset = 0)
443 throw std::runtime_error (
"memory not mapped");
448 throw std::out_of_range (
"offset out of bounds");
451 return static_cast<char*
> (_ptr) + offset;
460 int mbind (
int numa)
const noexcept
462 return join::mbind (_ptr, _size, numa);
484 if ((huge != 0) && (_size >= huge))
486 uint64_t size = (_size + huge - 1) & ~(huge - 1);
488 _ptr = ::mmap (
nullptr, size, PROT_READ | PROT_WRITE,
489 MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | MAP_HUGETLB, -1, 0);
490 if (_ptr != MAP_FAILED)
498 if ((errno != ENOMEM) && (errno != EINVAL))
500 throw std::system_error (errno, std::generic_category (),
"mmap failed");
504 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
505 if (_ptr == MAP_FAILED)
507 throw std::system_error (errno, std::generic_category (),
"mmap failed");
514 void cleanup () noexcept
516 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
518 ::munlock (_ptr, _size);
519 ::munmap (_ptr, _size);
530 void* _ptr =
nullptr;
539 template <
size_t Count,
size_t... Sizes>
552 explicit ShmMem (uint64_t size,
const std::string& name)
556 _size = (size + page - 1) & ~(page - 1);
557 if (_size >
static_cast<uint64_t
> (std::numeric_limits<off_t>::max ()))
559 throw std::overflow_error (
"size will overflow");
582 : _size (other._size)
583 , _name (std::move (other._name))
588 other._ptr =
nullptr;
602 _name = std::move (other._name);
607 other._ptr =
nullptr;
627 return _ptr !=
nullptr;
637 const void*
get (uint64_t offset = 0)
const
641 throw std::runtime_error (
"memory not mapped");
646 throw std::out_of_range (
"offset out of bounds");
649 return static_cast<const char*
> (_ptr) + offset;
659 void*
get (uint64_t offset = 0)
663 throw std::runtime_error (
"memory not mapped");
668 throw std::out_of_range (
"offset out of bounds");
671 return static_cast<char*
> (_ptr) + offset;
680 int mbind (
int numa)
const noexcept
682 return join::mbind (_ptr, _size, numa);
700 static int unlink (
const std::string& name)
noexcept
702 if (::shm_unlink (name.c_str ()) == -1)
708 lastError = std::error_code (errno, std::generic_category ());
724 _fd = ::shm_open (_name.c_str (), O_CREAT | O_RDWR | O_EXCL | O_CLOEXEC, 0644);
725 if ((_fd == -1) && (errno == EEXIST))
728 _fd = ::shm_open (_name.c_str (), O_RDWR | O_CLOEXEC, 0644);
733 throw std::system_error (errno, std::generic_category (),
"shm_open failed");
740 if (fstat (_fd, &st) == -1)
745 throw std::system_error (err, std::generic_category (),
"fstat failed");
749 if (
static_cast<uint64_t
> (st.st_size) != _size)
752 throw std::runtime_error (
"shared memory size mismatch");
757 if (::ftruncate (_fd, _size) == -1)
761 throw std::system_error (err, std::generic_category (),
"ftruncate failed");
765 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
767 if (_ptr == MAP_FAILED)
771 throw std::system_error (err, std::generic_category (),
"mmap failed");
778 void cleanup () noexcept
780 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
782 ::munlock (_ptr, _size);
783 ::munmap (_ptr, _size);
804 void* _ptr =
nullptr;
bump allocator owning its backends.
Definition memory.hpp:60
slab allocator owning a backend and managing one or more pools.
Definition slab_allocator.hpp:339
heap memory provider.
Definition memory.hpp:168
HeapMem(HeapMem &&other) noexcept
move constructor.
Definition memory.hpp:212
void * get(uint64_t offset=0)
get a pointer to the memory at a given offset.
Definition memory.hpp:284
bool mapped() const noexcept
check if the memory is allocated.
Definition memory.hpp:250
HeapMem(const HeapMem &other)=delete
copy constructor.
const void * get(uint64_t offset=0) const
get a const pointer to the memory at a given offset.
Definition memory.hpp:262
~HeapMem() noexcept
releases the memory.
Definition memory.hpp:241
HeapMem() noexcept=default
default constructor.
HeapMem & operator=(const HeapMem &other)=delete
copy assignment operator.
local anonymous memory provider.
Definition memory.hpp:321
int mlock() const noexcept
lock memory in RAM.
Definition memory.hpp:470
const void * get(uint64_t offset=0) const
get a const pointer to the memory at a given offset.
Definition memory.hpp:417
LocalMem & operator=(const LocalMem &other)=delete
copy assignment operator.
void * get(uint64_t offset=0)
get a pointer to the memory at a given offset.
Definition memory.hpp:439
LocalMem(const LocalMem &other)=delete
copy constructor.
LocalMem() noexcept=default
default constructor.
LocalMem(LocalMem &&other) noexcept
move constructor.
Definition memory.hpp:367
bool mapped() const noexcept
check if the memory is mapped.
Definition memory.hpp:405
~LocalMem() noexcept
releases the mapped memory.
Definition memory.hpp:396
posix shared memory provider.
Definition memory.hpp:537
bool mapped() const noexcept
check if the shared memory is mapped.
Definition memory.hpp:625
void * get(uint64_t offset=0)
get a pointer to the shared memory at a given offset.
Definition memory.hpp:659
ShmMem(const ShmMem &other)=delete
copy constructor.
ShmMem & operator=(const ShmMem &other)=delete
copy assignment operator.
static int unlink(const std::string &name) noexcept
destroy synchronization primitives and unlink the shared memory segment.
Definition memory.hpp:700
int mlock() const noexcept
lock memory in RAM.
Definition memory.hpp:690
ShmMem(ShmMem &&other) noexcept
move constructor.
Definition memory.hpp:581
~ShmMem() noexcept
unmaps the memory and closes the file descriptor.
Definition memory.hpp:616
ShmMem(uint64_t size, const std::string &name)
creates or opens a named shared memory segment.
Definition memory.hpp:552
const void * get(uint64_t offset=0) const
get a const pointer to the shared memory at a given offset.
Definition memory.hpp:637
Definition acceptor.hpp:32
uint64_t hugePageSize() noexcept
get the default huge page size.
Definition memory.hpp:92
uint64_t pageSize() noexcept
get the system page size.
Definition memory.hpp:82
int mlock(void *ptr, size_t size) noexcept
lock memory in RAM.
Definition memory.hpp:145
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:195
const std::string _name
Definition shared_futex_test.cpp:45
multiple producer multiple consumer ring buffer.
Definition queue.hpp:844
multiple producer single consumer ring buffer.
Definition queue.hpp:651
single producer single consumer ring buffer.
Definition queue.hpp:470
queue forward declarations.
Definition queue.hpp:1037
#define JOIN_UNLIKELY(x)
Definition utils.hpp:51