2#include <cosmos/error/ApiError.hxx>
3#include <cosmos/error/UsageError.hxx>
4#include <cosmos/proc/mman.hxx>
5#include <cosmos/utils.hxx>
9void* map(
const size_t length,
const MapSettings &settings) {
12 const auto flags = settings.flags.raw() | to_integral(settings.type);
15 settings.addr, length, settings.access.raw(),
16 flags, to_integral(settings.fd.raw()), settings.offset);
18 if (addr == MAP_FAILED) {
19 cosmos_throw (ApiError(
"mmap()"));
25void unmap(
void *addr,
const size_t length) {
26 if (::munmap(addr, length) != 0) {
27 cosmos_throw (ApiError(
"munmap()"));
31void sync(
void *addr,
const size_t length,
const SyncFlags flags) {
32 if (::msync(addr, length, flags.raw()) != 0) {
33 cosmos_throw (ApiError(
"msync()"));
37void* remap(
void *old_addr,
const size_t old_size,
const size_t new_size,
const RemapFlags flags, std::optional<void*> new_addr) {
38 if (flags[RemapFlag::FIXED] && !new_addr) {
39 cosmos_throw (UsageError(
"missing new_addr argument along with FIXED"));
40 }
else if (!flags[RemapFlag::FIXED] && new_addr) {
41 cosmos_throw (UsageError(
"unexpected new_addr argument without FIXED"));
44 auto ret = ::mremap(old_addr, old_size, new_size, flags.raw(), new_addr ? *new_addr : MAP_FAILED);
46 if (ret == MAP_FAILED) {
47 cosmos_throw (ApiError(
"mremap()"));
53void lock(
void *addr,
const size_t length,
const LockFlags flags) {
54 if (::mlock2(addr, length, flags.raw()) != 0) {
55 cosmos_throw (ApiError(
"mlock2()"));
59void unlock(
void *addr,
const size_t length) {
60 if (::munlock(addr, length) != 0) {
61 cosmos_throw (ApiError(
"munlock()"));
65void lock_all(
const LockAllFlags flags) {
66 if (::mlockall(flags.raw()) != 0) {
67 cosmos_throw (ApiError(
"mlockall()"));
72 if (::munlockall() != 0) {
73 cosmos_throw (ApiError(
"munlockall()"));
77void protect(
void *addr,
const size_t length,
const AccessFlags flags,
const ProtectFlags extra) {
79 const auto raw_flags = flags.raw() | extra.raw();
81 if (::mprotect(addr, length, raw_flags) != 0) {
82 cosmos_throw (ApiError(
"mprotect()"));
87 if (!page_size || (page_size & (page_size-1)) != 0) {
89 cosmos_throw (
UsageError(
"non-log2 TLB page size encountered"));
92 EnumBaseType log2 = 1;
94 while ((page_size & 0x1) != 1) {
99 constexpr auto MAX_TLB_LOG2 = 0x3F;
101 if (log2 > MAX_TLB_LOG2) {
104 cosmos_throw (
UsageError(
"requested TLB page size is too large"));
Exception type for logical usage errors within the application.
Flags used in MapSettings.
void setTLBPageSize(size_t page_size)
Sets the TLB page size if MapFlag::HUGETLB is set.