export module fmap;
|
|
|
|
import <string>;
|
|
import <iostream>;
|
|
import <atomic>;
|
|
import exceptions_helpers;
|
|
|
|
#include <stdint.h>
|
|
#include <endian.hpp>
|
|
#include <assert.h>
|
|
|
|
// Unix-y stuff
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/stat.h>
|
|
|
|
namespace archivist{
|
|
|
|
export using fmap_opt_value = uint32_t;
|
|
|
|
export enum class fmap_options : fmap_opt_value {
|
|
random_access = MADV_RANDOM,
|
|
sequence_access = MADV_SEQUENTIAL,
|
|
will_need = MADV_WILLNEED,
|
|
|
|
#ifdef MADV_DONTDUMP
|
|
no_dump = MADV_DONTDUMP,
|
|
#endif
|
|
};
|
|
|
|
inline namespace conversions {
|
|
export constexpr fmap_opt_value operator fmap_opt_value(fmap_options opt) {
|
|
return (fmap_opt_value)opt;
|
|
}
|
|
}
|
|
|
|
export constexpr size_t page_size = 4096;
|
|
|
|
|
|
export class region_ptr {
|
|
std::atomic_int* ref_count;
|
|
public:
|
|
void* region;
|
|
size_t len;
|
|
|
|
region()
|
|
noexcept
|
|
: ref_count{nullptr}
|
|
, region{nullptr}
|
|
, len{0}
|
|
{}
|
|
|
|
region_ptr (
|
|
const size_t length,
|
|
const int prot,
|
|
const int flags,
|
|
const int fd,
|
|
const off_t offset
|
|
)
|
|
noexcept(false)
|
|
: ref_count{new std::atomic_int(1)}
|
|
{
|
|
auto mmap_ret = mmap(nullptr, length, prot, flags, fd, offset);
|
|
throw_errno_if(mmap_ret==MAP_FAILED);
|
|
region = mmap_ret;
|
|
len = length;
|
|
}
|
|
|
|
region_ptr(const region_ptr& oth)
|
|
noexcept
|
|
: ref_count(oth.ref_count)
|
|
, region(oth.region)
|
|
, len(oth.len)
|
|
{
|
|
ref_count->fetch_add(1);
|
|
}
|
|
|
|
~region_ptr()
|
|
{
|
|
if(!ref_count || !region)
|
|
return;
|
|
auto v = ref_count->fetch_sub(1);
|
|
if(v==1)
|
|
{
|
|
delete ref_count;
|
|
munmap(region, length);
|
|
}
|
|
}
|
|
|
|
bool operation bool()
|
|
noexcept
|
|
{
|
|
return region && ref_count && len;
|
|
}
|
|
}
|
|
|
|
export using open_opt_flags = int;
|
|
|
|
export enum class open_options : open_opt_flags {
|
|
append = O_APPEND,
|
|
create = O_CREAT,
|
|
async = O_ASYNC,
|
|
direct = O_DIRECT,
|
|
data_sync = O_DSYNC,
|
|
file_sync = O_SYNC,
|
|
exclusive = O_EXCL,
|
|
no_access_time = O_NOATIME,
|
|
no_follow = O_NOFOLLOW,
|
|
temporary = O_TEMP,
|
|
truncate = O_TRUC
|
|
};
|
|
|
|
export using open_opt_mode = int;
|
|
|
|
export enum class open_modes : open_opt_mode {
|
|
user_read = S_IRUSR,
|
|
user_write = S_IWUSR,
|
|
user_exec = S_IXUSR,
|
|
group_read = S_IRGRP,
|
|
group_write = S_IWGRP,
|
|
group_exec = S_IXGRP,
|
|
other_read = S_IROTH,
|
|
other_write = S_IWOTH,
|
|
other_exec = S_IXOTH,
|
|
set_uid = S_ISUID,
|
|
set_gid = S_ISGID,
|
|
sticky_bit = S_ISVTX
|
|
};
|
|
|
|
inline namespace conversions {
|
|
export constexpr open_opt_flags operator open_opt_flags(open_options opt) {
|
|
return (open_opt_flags)opt;
|
|
}
|
|
export constexpr open_opt_mode operator open_opt_mode(open_modes opt) {
|
|
return (open_opt_mode)opt;
|
|
}
|
|
}
|
|
|
|
export class abstract_fd {
|
|
std::atomic_int* ref_count;
|
|
int fd = 0;
|
|
public:
|
|
abstract_fd(const std::string& pathname, open_opt_flags flags, mode_t mode)
|
|
{
|
|
|
|
}
|
|
|
|
int operator int() {
|
|
if(!fd) throw std::runtime_error("reading a closed fd");
|
|
return fd;
|
|
}
|
|
}
|
|
|
|
export template<typename T>
|
|
class farray_ptr {
|
|
region_ptr ptr;
|
|
public:
|
|
farray_ptr(const std::string& file)
|
|
{
|
|
|
|
}
|
|
};
|
|
}
|
|
|
|
|
|
|
|
|
|
|