`memory_pages` is a small library provinig a cross-platform API to request pages from kernel with certain premisions

Overview

memory_pages: High level API for low level memory management

While using low-level memory management in a project can provide substantial benefits, it is very often cumbersome. The API-s differ significantly between OS-s and have many pitfalls one can easily fall into. But what if, all the unsafety, all the platform-specific differences could be simply abstracted away? What if you could do very fine-grain memory adjustments without ever seeing a pointer? This crate provides such zero-cost abstractions.

For who it is for?

This crate is mostly meant for performance critical projects, especially ones dealing with huge amounts of data. The APIs and types provided by this crate are not universal solutions to all problems. Since this crate is designed with those applications in mind, it can achieve great improvements(2x faster allocations) over using standard memory management. Another example of strengths of this crate is PagedVec-s clear_decommit function that not only clears the vector - it also informs the OS about the vec being cleared. This information allows the physical memory pages storing the data to be decommited, making the PagedVec occupy no space in the RAM until it is written into, while still having the required space reserved.

What does memory_pages provide?

Safety by strict typing

One of the common pitfalls of using low-level APIs is the ease of making mistakes regarding page permissions. Mixing them up can at best lead to a segfault, and at worst introduce serious security vulnerabilities. This crate leverages rusts type system(zero sized marker types) to make certain kinds of errors simply impossible. Trying to acquire a mutable reference, and writing into data that was marked as read-only would normally lead to a segfault and crash at runtime. A collection of memory pages, called, unsurprisingly, Pages, must have a AllowWrite marker type, in order to implement functions and traits that allow for it to be written into. This turns all sorts of horrible runtime errors into compile-time ones, making it impossible to miss them.

Holds your hand, but does not hold you back.

This crates core philosophy is to always guide, never restrict. Almost everything that can be done with this crate can be done without ever seeing the word unsafe. While references and the special FnRef type are automatically invalidated on permission changes, those safety restrictions can be easily subverted by using unsafe functions and pointers. There are some very unsafe APIs, which are locked behind feature gates.

Highly performant

Getting memory pages directly and cutting the middle man can be 2x faster!

Memory acquisition route Speed of allocating space for 50 MB structure
Standard Allocator 6.5299 µs
Allocating pages manually 3.5670 µs

Provide useful hints to the kernel

Use functions such as adivse_use_soon, advise_use_seq, adivse_use_rng to provide memory usage hints.

With great power comes great responsibility

Just as this crate can greatly improve performance and reduce memory usage, it can also decrease performance and increase memory usage. While achieving results substantially worse than using default allocators is pretty hard and requires being very very sloppy, it is harder to squeeze everything out of this crate. Gain from usage depends on the competence of the user. As a good example, in some tests, a 2x allocation time reduction was achieved. But those examples were extensively tweaked, to find out the maximal potential performance gain.

Kernel memory usage hints

Is the memory use going to be sequential or random? Provide optional hints to the kernel which may improve performance in some cases.

Examples

Dealing with pages directly

Data storage

use memory_pages::*;
let mut memory = Pages<AllowRead,AllowWrite,DenyExec> = Pages::new(0x40000);
read_data(&mut memory).unwrap();
validate_data(&mut memory);

Prevent writes

use memory_pages::*;
let mut memory = Pages<AllowRead,AllowWrite,DenyExec> = Pages::new(0x40000);
read_data(&mut memory).unwrap();
let mut memory = memory.deny_write();
// `memory` is now read-only and a write attempt would case a segfault
// Because of that, borrowing it as `&mut [u8]` is now not avalible, so this would not compile if used
// write_data(&mut memory);

x86_64 function assembled at run-time

This example does not work on windows, due to differences in the calling conventions

use memory_pages::*;
let mut memory:Pages<AllowRead,AllowWrite,DenyExec> = Pages::new(0x4000);
// hex-encoded X86_64 assembly for adding 2 numbers
// lea 	rax, [rdi+rsi]
memory[0] = 0x48;
memory[1] = 0x8d;
memory[2] = 0x04;
memory[3] = 0x37;
// ret
memory[4] = 0xC3;
// Sets execution to allow and write to deny to prevent exploits
let memory = memory.set_protected_exec();
//FnRef ensures proper lifetimes!
let add:FnRef<unsafe extern "C" fn(u64,u64)->u64> = unsafe{memory.get_fn(0)};
unsafe{assert_eq!(add.call((43,34)),77)};

PagedVec

Create new vec

let mut vec = PagedVec::new(0x10000);
for _ in 1_000_000{
    vec.push(102.32);
}

Clear and deccomit

let mut vec = PagedVec::new(0x10000);
for _ in 1_000_000{
    vec.push(102.32);
}
// Clears vec, keeping the capacity but freeing the phisical memory,
// which is automaticaly reclaimed as it is filled back up.
vec.clear_decommit();
You might also like...
Small, clean, easy to use programming language

Thistle A modern, simplistic multi-paradigm language supporting object-oriented features Hello World! import IO object Main def main(): unit

Small programs written in Rust. Warm up for the upcoming Selenium Manager

Rust Examples This repository contains several example programs written in Rust. Selenium Manager These examples are used as warm up for the upcoming

A small in-memory key value database for rust

SmollDB Small in-memory key value database for rust This is a small in-memory key-value database, which can be easly backed up in a file or stream and

RcLite: small, fast, and memory-friendly reference counting for Rust

RcLite: small, fast, and memory-friendly reference counting RcLite is a lightweight reference-counting solution for Rust that serves as an alternative

A small, nutty dependently typed language.
A small, nutty dependently typed language.

pistachio I want to learn about how theorem provers and dependently typed languages are implemented. This is a little repo for experimentation. elabor

An inline SIMD accelerated hashmap designed for small amount of data.
An inline SIMD accelerated hashmap designed for small amount of data.

Small-Map An inline SIMD accelerated hashmap designed for small amount of data. Usage use small_map::SmallMap; // Don't worry about the 16 here. // Wh

Rust library for hardware accelerated drawing of 2D shapes, images, and text, with an easy to use API.
Rust library for hardware accelerated drawing of 2D shapes, images, and text, with an easy to use API.

Speedy2D Hardware-accelerated drawing of shapes, images, and text, with an easy to use API. Speedy2D aims to be: The simplest Rust API for creating a

A simple heads or tails (cross and pile) on Solana

cross-pile (Coin flip) A heads or tails (cross and pile) on Solana. It's meant to serve as an example of how to use solrand, a randomness Oracle: http

A cloud-native distributed serverless workers platform.

rusty-workers A cloud-native distributed serverless workers platform. Features JavaScript and WebAssembly engine powered by V8 Fetch API Highly scalab

Owner
Young programmer from Poland, interested in writing 3D graphics software and procedural generation
null
Cross-platform GUI for youtube-dl made with Iced

youtube-dl-gui Cross-platform GUI for youtube-dl made with Iced. Installation Before you install this crate, make sure you have youtube-dl and FFmpeg

Hristo Gochev 4 Feb 27, 2023
A kernel version manager for systemd-boot and AOSC OS

Your systemd-boot's best friend ever (Implemented in Rust) A kernel version manager for systemd-boot and AOSC OS Usage First initialize friend and sys

AOSC-Dev 20 Oct 9, 2022
💩 Small HTTP client for the Webpurify API following the sans-io approach 🦀

?? tame-webpurify Super simple client for the WebPurify REST API What is this? An incredibly small library to interact with the https://www.webpurify.

Embark 8 May 1, 2023
List public items (public API) of Rust library crates. Enables diffing public API between releases.

cargo wrapper for this library You probably want the cargo wrapper to this library. See https://github.com/Enselic/cargo-public-items. public_items Li

Martin Nordholts 20 Dec 26, 2022
A small utility for modifying ELF shared library loading order.

elfpromote A small utility for modifying ELF shared library loading order. Usage $ cargo install elfpromote $ ldd blueboat_server linux-vdso.s

Heyang Zhou 5 Jul 21, 2022
Uma lib para a API do Brasil API (para o Rust)

Uma lib para a API do BrasilAPI (para o Rust) Features CEP (Zip code) DDD Bank CNPJ IBGE Feriados Nacionais Tabela FIPE ISBN Registros de domínios br

Pedro Augusto 6 Dec 13, 2022
:crab: Small exercises to get you used to reading and writing Rust code!

rustlings ?? ❤️ Greetings and welcome to rustlings. This project contains small exercises to get you used to reading and writing Rust code. This inclu

The Rust Programming Language 33.1k Jan 2, 2023
Fegeya Elitebuild, small, powerful build system. Written in Rust.

Fegeya Elitebuild Small, powerful, work-in-progress build system. Written in Rust. Features: No functions (all are built-ins) All variables are global

Ferhat Geçdoğan 25 Nov 9, 2022
Small ray tracer demo of the F# to Rust language transpiler in Fable 4.x

Small ray tracer demo of the F# to Rust language transpiler in Fable 4.x

null 45 Nov 16, 2022
This project contains small exercises to get you used to reading and writing Rust code

rustlings ?? ❤️ Greetings and welcome to rustlings. This project contains small exercises to get you used to reading and writing Rust code. This inclu

Cynthia Tran 1 May 24, 2022