MMU is a small utility library that provides abstractions over memory mapped files.
Installation
To build MMU from source you will need a C++14 compiler and CMake.
Usage
MMU offers the following utilities:
- Abstract untyped buffers encapsulating a data pointer and a size that can be allocated from the C standard library using
MMU::make_buffer, mapped from a file usingMMU::file_buffer, or wrap a pre-allocated memory area usingMMU::static_buffer. - Typed one-dimensional arrays wrapping a buffer, offset, stride, and size that can be allocated from the C standard library using
MMU::make_array, mapped from a file usingMMU::file_array, or wrap a pre-allocated array usingMMU::static_array. - Typed two-dimensional arrays wrapping a buffer, offset, two strides, and two sizes that can be allocated from the C standard library using
MMU::make_array2d, mapped from a file usingMMU::file_array2d, or wrap a pre-allocated array usingMMU::static_array2d. - An untyped allocator managing a pool of swap files that can be created with
MMU::buffer_pool. - Typed allocators wrapping a pool of swap files for use with STL containers represented by the
MMU::Allocator<T>class. - A convenient abstraction around the dynamic linker that can be instantiated using
MMU::shared_library. - A small options container
MMU::MMapOptionsto configure the properties of a memory mapping. - A small options container
MMU::PoolOptionsto configure the properties of a swap file pool. - A small options container
MMU::LibraryOptionsto configure the behaviour when loading a shared library. - Utility functions to find the executable file (
MMU::program_file()), identify the host system (MMU::runtime_id()), get the system page size (MMU::page_size()), and get the memory used by the current process (MMU::get_resident_size(),MMU::max_resident_size()).
Here's a simple usage example to get you started:
#include <cstdio>
#include <string>
#include <algorithm>
#include <MMU/MMU.hpp>
int main(int nargs, const char **args) {
MMU::set_program_name(nargs > 0 ? args[0] : __FUNCTION__);
# if defined(__EXCEPTIONS)
try
# endif
{
auto array = MMU::file_array<const char>(__FILE__);
MMU_ASSERT(array.contiguous());
MMU_ASSERT(array.begin() != array.end());
auto slice = array.slice(1, 7, 2);
MMU_ASSERT(!slice.contiguous());
MMU_ASSERT(std::equal(slice.begin(), slice.end(), "icue<sd"));
typedef std::basic_string<
char, std::char_traits<char>,
MMU::Allocator<char>
> mmu_string_t;
auto pool = MMU::buffer_pool("buffer_pool.d");
mmu_string_t hello("Hello world!", pool);
MMU_ASSERT(hello[6] == 'w');
auto libc = MMU::shared_library(nullptr);
auto puts = libc->get<void, const char *>("puts");
if (MMU_UNLIKELY(!puts)) MMU_ASSERT_ERROR(libc->last_error());
puts(hello.c_str());
return 0;
}
# if defined(__EXCEPTIONS)
catch (const std::exception &exn) {
fprintf(stderr, "%s: Error: %s\n", MMU::program_name(), exn.what());
return 1;
}
# endif
}