25#ifndef JOIN_CORE_MEMORY_HPP
26#define JOIN_CORE_MEMORY_HPP
33#include <system_error>
52 template <
typename Backend,
size_t Count,
size_t... Sizes>
56 template <
typename Backend,
template <
typename,
typename>
class SyncPolicy>
59 template <
typename,
typename>
62 template <
typename,
typename>
65 template <
typename,
typename>
76 inline int mbind (
void* ptr,
size_t size,
int numa)
noexcept
78 if (ptr ==
nullptr || numa < 0 || numa > (
static_cast<int> (
sizeof (
unsigned long) * 8) - 1))
84 unsigned long mask = (1UL << numa);
85 if (::mbind (ptr, size, MPOL_BIND, &mask,
sizeof (mask) * 8, MPOL_MF_STRICT) == -1)
87 lastError = std::error_code (errno, std::generic_category ());
101 inline int mlock (
void* ptr,
size_t size)
noexcept
111 lastError = std::error_code (errno, std::generic_category ());
124 template <
size_t Count,
size_t... Sizes>
138 long sc = sysconf (_SC_PAGESIZE);
139 uint64_t pageSize = (sc > 0) ?
static_cast<uint64_t
> (sc) : _defaultPageSize;
140 _size = (size + pageSize - 1) & ~(pageSize - 1);
163 : _size (other._size)
167 other._ptr =
nullptr;
183 other._ptr =
nullptr;
203 const void*
get (uint64_t offset = 0)
const
207 throw std::runtime_error (
"memory not mapped");
212 throw std::out_of_range (
"offset out of bounds");
215 return static_cast<const char*
> (_ptr) + offset;
225 void*
get (uint64_t offset = 0)
229 throw std::runtime_error (
"memory not mapped");
234 throw std::out_of_range (
"offset out of bounds");
237 return static_cast<char*
> (_ptr) + offset;
246 int mbind (
int numa)
const noexcept
248 return join::mbind (_ptr, _size, numa);
268 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE,
269 MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE | MAP_HUGETLB, -1, 0);
270 if ((_ptr == MAP_FAILED) && ((errno == ENOMEM) || (errno == EINVAL)))
274 ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);
277 if (_ptr == MAP_FAILED)
279 throw std::system_error (errno, std::generic_category (),
"mmap failed");
286 void cleanup () noexcept
288 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
290 ::munlock (_ptr, _size);
291 ::munmap (_ptr, _size);
299 static constexpr uint64_t _defaultPageSize = 4096;
305 void* _ptr =
nullptr;
314 template <
size_t Count,
size_t... Sizes>
327 explicit ShmMem (uint64_t size,
const std::string& name)
330 long sc = sysconf (_SC_PAGESIZE);
331 uint64_t pageSize = (sc > 0) ?
static_cast<uint64_t
> (sc) : _defaultPageSize;
332 _size = (size + pageSize - 1) & ~(pageSize - 1);
334 if (_size >
static_cast<uint64_t
> (std::numeric_limits<off_t>::max ()))
336 throw std::overflow_error (
"size will overflow");
360 : _size (other._size)
361 , _name (std::move (other._name))
366 other._ptr =
nullptr;
380 _name = std::move (other._name);
385 other._ptr =
nullptr;
406 const void*
get (uint64_t offset = 0)
const
410 throw std::runtime_error (
"memory not mapped");
415 throw std::out_of_range (
"offset out of bounds");
418 return static_cast<const char*
> (_ptr) + offset;
428 void*
get (uint64_t offset = 0)
432 throw std::runtime_error (
"memory not mapped");
437 throw std::out_of_range (
"offset out of bounds");
440 return static_cast<char*
> (_ptr) + offset;
449 int mbind (
int numa)
const noexcept
451 return join::mbind (_ptr, _size, numa);
469 static int unlink (
const std::string& name)
noexcept
471 if (::shm_unlink (name.c_str ()) == -1)
477 lastError = std::error_code (errno, std::generic_category ());
493 _fd = ::shm_open (_name.c_str (), O_CREAT | O_RDWR | O_EXCL | O_CLOEXEC, 0644);
494 if ((_fd == -1) && (errno == EEXIST))
497 _fd = ::shm_open (_name.c_str (), O_RDWR | O_CLOEXEC, 0644);
502 throw std::system_error (errno, std::generic_category (),
"shm_open failed");
509 if (fstat (_fd, &st) == -1)
513 throw std::system_error (err, std::generic_category (),
"fstat failed");
516 if (
static_cast<uint64_t
> (st.st_size) != _size)
519 throw std::runtime_error (
"shared memory size mismatch");
524 if (::ftruncate (_fd, _size) == -1)
528 throw std::system_error (err, std::generic_category (),
"ftruncate failed");
532 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_HUGETLB, _fd, 0);
533 if ((_ptr == MAP_FAILED) && ((errno == ENOMEM) || (errno == EINVAL)))
536 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
539 if (_ptr == MAP_FAILED)
543 throw std::system_error (err, std::generic_category (),
"mmap failed");
550 void cleanup () noexcept
552 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
554 ::munlock (_ptr, _size);
555 ::munmap (_ptr, _size);
570 static constexpr uint64_t _defaultPageSize = 4096;
579 void* _ptr =
nullptr;
memory arena owning backend and managing one or more pools.
Definition memory.hpp:53
local anonymous memory provider.
Definition memory.hpp:122
LocalMem(uint64_t size)
allocates a local anonymous memory segment.
Definition memory.hpp:136
int mlock() const noexcept
lock memory in RAM.
Definition memory.hpp:256
const void * get(uint64_t offset=0) const
get a const pointer to the memory at a given offset.
Definition memory.hpp:203
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:225
LocalMem(const LocalMem &other)=delete
copy constructor.
LocalMem(LocalMem &&other) noexcept
move constructor.
Definition memory.hpp:162
~LocalMem() noexcept
releases the mapped memory.
Definition memory.hpp:191
posix shared memory provider.
Definition memory.hpp:312
void * get(uint64_t offset=0)
get a pointer to the shared memory at a given offset.
Definition memory.hpp:428
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:469
int mlock() const noexcept
lock memory in RAM.
Definition memory.hpp:459
ShmMem(ShmMem &&other) noexcept
move constructor.
Definition memory.hpp:359
~ShmMem() noexcept
unmaps the memory and closes the file descriptor.
Definition memory.hpp:394
ShmMem(uint64_t size, const std::string &name)
creates or opens a named shared memory segment.
Definition memory.hpp:327
const void * get(uint64_t offset=0) const
get a const pointer to the shared memory at a given offset.
Definition memory.hpp:406
Definition acceptor.hpp:32
int mlock(void *ptr, size_t size) noexcept
lock memory in RAM.
Definition memory.hpp:101
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:882
multiple producer single consumer ring buffer.
Definition queue.hpp:682
single producer single consumer ring buffer.
Definition queue.hpp:502
queue forward declarations.
Definition queue.hpp:1083
#define JOIN_UNLIKELY(x)
Definition utils.hpp:47