25#ifndef JOIN_CORE_MEMORY_HPP
26#define JOIN_CORE_MEMORY_HPP
33#include <system_error>
50 template <
typename Backend,
size_t Count,
size_t... Sizes>
54 template <
typename Backend,
template <
typename,
typename>
class SyncPolicy>
56 template <
typename,
typename>
58 template <
typename,
typename>
60 template <
typename,
typename>
70 inline int mbind (
void* ptr,
size_t size,
int numa)
noexcept
72 if (ptr ==
nullptr || numa < 0)
78 unsigned long mask = (1UL << numa);
79 if (
::mbind (ptr, size, MPOL_BIND, &mask,
sizeof (mask) * 8, MPOL_MF_STRICT) == -1)
81 lastError = std::error_code (errno, std::generic_category ());
94 inline int mlock (
void* ptr,
size_t size)
noexcept
104 lastError = std::error_code (errno, std::generic_category ());
117 template <
size_t Count,
size_t... Sizes>
131 long sc = sysconf (_SC_PAGESIZE);
132 uint64_t pageSize = (sc > 0) ?
static_cast<uint64_t
> (sc) : 4096;
133 _size = (size + pageSize - 1) & ~(pageSize - 1);
156 : _size (other._size)
160 other._ptr =
nullptr;
176 other._ptr =
nullptr;
196 inline const void*
get (uint64_t offset = 0)
const
200 throw std::runtime_error (
"memory not mapped");
205 throw std::out_of_range (
"offset out of bounds");
208 return static_cast<const char*
> (_ptr) + offset;
218 inline void*
get (uint64_t offset = 0)
222 throw std::runtime_error (
"memory not mapped");
227 throw std::out_of_range (
"offset out of bounds");
230 return static_cast<char*
> (_ptr) + offset;
259 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
260 if ((_ptr == MAP_FAILED) && ((errno == ENOMEM) || (errno == EINVAL)))
263 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
266 if (_ptr == MAP_FAILED)
268 throw std::system_error (errno, std::generic_category (),
"mmap failed");
275 void cleanup () noexcept
277 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
279 ::munlock (_ptr, _size);
280 ::munmap (_ptr, _size);
291 void* _ptr =
nullptr;
300 template <
size_t Count,
size_t... Sizes>
313 explicit ShmMem (uint64_t size,
const std::string& name)
316 long sc = sysconf (_SC_PAGESIZE);
317 uint64_t pageSize = (sc > 0) ?
static_cast<uint64_t
> (sc) : 4096;
318 _size = (size + pageSize - 1) & ~(pageSize - 1);
320 if (_size >
static_cast<uint64_t
> (std::numeric_limits<off_t>::max ()))
322 throw std::overflow_error (
"size will overflow");
346 : _size (other._size)
347 , _name (std::move (other._name))
352 other._ptr =
nullptr;
366 _name = std::move (other._name);
371 other._ptr =
nullptr;
392 inline const void*
get (uint64_t offset = 0)
const
396 throw std::runtime_error (
"memory not mapped");
401 throw std::out_of_range (
"offset out of bounds");
404 return static_cast<const char*
> (_ptr) + offset;
414 inline void*
get (uint64_t offset = 0)
418 throw std::runtime_error (
"memory not mapped");
423 throw std::out_of_range (
"offset out of bounds");
426 return static_cast<char*
> (_ptr) + offset;
453 static int unlink (
const std::string& name)
noexcept
455 if (::shm_unlink (name.c_str ()) == -1)
461 lastError = std::error_code (errno, std::generic_category ());
477 _fd = ::shm_open (_name.c_str (), O_CREAT | O_RDWR | O_EXCL | O_CLOEXEC, 0644);
478 if ((_fd == -1) && (errno == EEXIST))
481 _fd = ::shm_open (_name.c_str (), O_RDWR | O_CLOEXEC, 0644);
486 throw std::system_error (errno, std::generic_category (),
"shm_open failed");
493 if (fstat (_fd, &st) == -1)
497 throw std::system_error (err, std::generic_category (),
"fstat failed");
500 if (
static_cast<uint64_t
> (st.st_size) != _size)
503 throw std::runtime_error (
"shared memory size mismatch");
508 if (::ftruncate (_fd, _size) == -1)
512 throw std::system_error (err, std::generic_category (),
"ftruncate failed");
516 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_HUGETLB, _fd, 0);
517 if ((_ptr == MAP_FAILED) && ((errno == ENOMEM) || (errno == EINVAL)))
520 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
523 if (_ptr == MAP_FAILED)
527 throw std::system_error (err, std::generic_category (),
"mmap failed");
534 void cleanup () noexcept
536 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
538 ::munlock (_ptr, _size);
539 ::munmap (_ptr, _size);
560 void* _ptr =
nullptr;
memory arena owning backend and managing one or more pools.
Definition memory.hpp:51
local anonymous memory provider.
Definition memory.hpp:115
LocalMem(uint64_t size)
allocates a local anonymous memory segment.
Definition memory.hpp:129
int mlock() const noexcept
lock memory in RAM.
Definition memory.hpp:247
int mbind(int numa) const noexcept
bind memory to a NUMA node.
Definition memory.hpp:238
const void * get(uint64_t offset=0) const
get a const pointer to the memory at a given offset.
Definition memory.hpp:196
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:218
LocalMem(const LocalMem &other)=delete
copy constructor.
LocalMem(LocalMem &&other) noexcept
move constructor.
Definition memory.hpp:155
~LocalMem() noexcept
releases the mapped memory.
Definition memory.hpp:184
posix shared memory provider.
Definition memory.hpp:298
void * get(uint64_t offset=0)
get a pointer to the shared memory at a given offset.
Definition memory.hpp:414
ShmMem(const ShmMem &other)=delete
copy constructor.
ShmMem & operator=(const ShmMem &other)=delete
copy assignment operator.
int mbind(int numa) const noexcept
bind memory to a NUMA node.
Definition memory.hpp:434
static int unlink(const std::string &name) noexcept
destroy synchronization primitives and unlink the shared memory segment.
Definition memory.hpp:453
int mlock() const noexcept
lock memory in RAM.
Definition memory.hpp:443
ShmMem(ShmMem &&other) noexcept
move constructor.
Definition memory.hpp:345
~ShmMem() noexcept
unmaps the memory and closes the file descriptor.
Definition memory.hpp:380
ShmMem(uint64_t size, const std::string &name)
creates or opens a named shared memory segment.
Definition memory.hpp:313
const void * get(uint64_t offset=0) const
get a const pointer to the shared memory at a given offset.
Definition memory.hpp:392
Definition acceptor.hpp:32
int mlock(void *ptr, size_t size) noexcept
lock memory in RAM.
Definition memory.hpp:94
int mbind(void *ptr, size_t size, int numa) noexcept
bind memory to a NUMA node.
Definition memory.hpp:70
std::error_code make_error_code(join::Errc code) noexcept
Create an std::error_code object.
Definition error.cpp:150
const std::string _name
Definition semaphore_test.cpp:39
multiple producer multiple consumer ring buffer.
Definition queue.hpp:520
multiple producer single consumer ring buffer.
Definition queue.hpp:433
single producer single consumer ring buffer.
Definition queue.hpp:364
queue forward declarations.
Definition queue.hpp:586
#define JOIN_UNLIKELY(x)
Definition utils.hpp:47