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, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
269 if ((_ptr == MAP_FAILED) && ((errno == ENOMEM) || (errno == EINVAL)))
272 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
275 if (_ptr == MAP_FAILED)
277 throw std::system_error (errno, std::generic_category (),
"mmap failed");
284 void cleanup () noexcept
286 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
288 ::munlock (_ptr, _size);
289 ::munmap (_ptr, _size);
297 static constexpr uint64_t _defaultPageSize = 4096;
303 void* _ptr =
nullptr;
312 template <
size_t Count,
size_t... Sizes>
325 explicit ShmMem (uint64_t size,
const std::string& name)
328 long sc = sysconf (_SC_PAGESIZE);
329 uint64_t pageSize = (sc > 0) ?
static_cast<uint64_t
> (sc) : _defaultPageSize;
330 _size = (size + pageSize - 1) & ~(pageSize - 1);
332 if (_size >
static_cast<uint64_t
> (std::numeric_limits<off_t>::max ()))
334 throw std::overflow_error (
"size will overflow");
358 : _size (other._size)
359 , _name (std::move (other._name))
364 other._ptr =
nullptr;
378 _name = std::move (other._name);
383 other._ptr =
nullptr;
404 const void*
get (uint64_t offset = 0)
const
408 throw std::runtime_error (
"memory not mapped");
413 throw std::out_of_range (
"offset out of bounds");
416 return static_cast<const char*
> (_ptr) + offset;
426 void*
get (uint64_t offset = 0)
430 throw std::runtime_error (
"memory not mapped");
435 throw std::out_of_range (
"offset out of bounds");
438 return static_cast<char*
> (_ptr) + offset;
447 int mbind (
int numa)
const noexcept
449 return join::mbind (_ptr, _size, numa);
467 static int unlink (
const std::string& name)
noexcept
469 if (::shm_unlink (name.c_str ()) == -1)
475 lastError = std::error_code (errno, std::generic_category ());
491 _fd = ::shm_open (_name.c_str (), O_CREAT | O_RDWR | O_EXCL | O_CLOEXEC, 0644);
492 if ((_fd == -1) && (errno == EEXIST))
495 _fd = ::shm_open (_name.c_str (), O_RDWR | O_CLOEXEC, 0644);
500 throw std::system_error (errno, std::generic_category (),
"shm_open failed");
507 if (fstat (_fd, &st) == -1)
511 throw std::system_error (err, std::generic_category (),
"fstat failed");
514 if (
static_cast<uint64_t
> (st.st_size) != _size)
517 throw std::runtime_error (
"shared memory size mismatch");
522 if (::ftruncate (_fd, _size) == -1)
526 throw std::system_error (err, std::generic_category (),
"ftruncate failed");
530 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_HUGETLB, _fd, 0);
531 if ((_ptr == MAP_FAILED) && ((errno == ENOMEM) || (errno == EINVAL)))
534 _ptr = ::mmap (
nullptr, _size, PROT_READ | PROT_WRITE, MAP_SHARED, _fd, 0);
537 if (_ptr == MAP_FAILED)
541 throw std::system_error (err, std::generic_category (),
"mmap failed");
548 void cleanup () noexcept
550 if ((_ptr !=
nullptr) && (_ptr != MAP_FAILED))
552 ::munlock (_ptr, _size);
553 ::munmap (_ptr, _size);
568 static constexpr uint64_t _defaultPageSize = 4096;
577 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:310
void * get(uint64_t offset=0)
get a pointer to the shared memory at a given offset.
Definition memory.hpp:426
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:467
int mlock() const noexcept
lock memory in RAM.
Definition memory.hpp:457
ShmMem(ShmMem &&other) noexcept
move constructor.
Definition memory.hpp:357
~ShmMem() noexcept
unmaps the memory and closes the file descriptor.
Definition memory.hpp:392
ShmMem(uint64_t size, const std::string &name)
creates or opens a named shared memory segment.
Definition memory.hpp:325
const void * get(uint64_t offset=0) const
get a const pointer to the shared memory at a given offset.
Definition memory.hpp:404
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:838
multiple producer single consumer ring buffer.
Definition queue.hpp:654
single producer single consumer ring buffer.
Definition queue.hpp:508
queue forward declarations.
Definition queue.hpp:982
#define JOIN_UNLIKELY(x)
Definition utils.hpp:47