Skip to content

Commit

Permalink
Break out allocator into separate crate
Browse files Browse the repository at this point in the history
  • Loading branch information
udoprog committed Mar 13, 2024
1 parent 662b3ed commit dbae2cf
Show file tree
Hide file tree
Showing 22 changed files with 114 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
strategy:
fail-fast: false
matrix:
package: [musli, musli-common, musli-storage, musli-descriptive, musli-wire, musli-json, musli-value]
package: [musli, musli-allocator, musli-common, musli-storage, musli-descriptive, musli-wire, musli-json, musli-value]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand Down
20 changes: 20 additions & 0 deletions crates/musli-allocator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[package]
name = "musli-allocator"
version = "0.0.96"
authors = ["John-John Tedro <udoprog@tedro.se>"]
edition = "2021"
documentation = "https://docs.rs/musli"
readme = "README.md"
homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["no-std", "memory-management", "rust-patterns"]

[features]
default = ["std"]
std = ["alloc", "musli/std"]
alloc = ["musli/alloc"]

[dependencies]
musli = { path = "../musli", version = "0.0.96", default-features = false }
17 changes: 17 additions & 0 deletions crates/musli-allocator/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# musli-allocator

[<img alt="github" src="https://img.shields.io/badge/github-udoprog/musli-8da0cb?style=for-the-badge&logo=github" height="20">](https://github.com/udoprog/musli)
[<img alt="crates.io" src="https://img.shields.io/crates/v/musli-allocator.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/musli-allocator)
[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-musli--allocator-66c2a5?style=for-the-badge&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/musli-allocator)
[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/udoprog/musli/ci.yml?branch=main&style=for-the-badge" height="20">](https://github.com/udoprog/musli/actions?query=branch%3Amain)

Allocation support for [Müsli].

This crate contains two types of allocators:
* The [`System`] allocator, which uses the system allocation facilities.
Particularly [`std::alloc::System`].
* The [`Stack`] allocator, which can allocate buffers from a fixed-size
slice.

[Müsli]: <https://docs.rs/musli>
[`std::alloc::System`]: https://doc.rust-lang.org/std/alloc/struct.System.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use musli::context::Buf;

use crate::allocator::Allocator;
use crate::Allocator;

/// An empty buffer.
pub struct EmptyBuf;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ use core::ptr;
use core::slice;
use core::str;

/// An error raised when we are at capacity.
#[non_exhaustive]
pub(crate) struct CapacityError;
pub struct CapacityError;

/// A fixed capacity vector allocated on the stack.
pub struct FixedVec<T, const N: usize> {
data: [MaybeUninit<T>; N],
len: usize,
}

impl<T, const N: usize> FixedVec<T, N> {
pub(crate) const fn new() -> FixedVec<T, N> {
/// Construct a new empty fixed vector.
pub const fn new() -> FixedVec<T, N> {
unsafe {
FixedVec {
data: MaybeUninit::uninit().assume_init(),
Expand Down Expand Up @@ -78,7 +81,8 @@ impl<T, const N: usize> FixedVec<T, N> {
Ok(())
}

pub(crate) fn try_push(&mut self, element: T) -> Result<(), CapacityError> {
/// Try to push an element onto the fixed vector.
pub fn try_push(&mut self, element: T) -> Result<(), CapacityError> {
if self.len >= N {
return Err(CapacityError);
}
Expand All @@ -91,7 +95,8 @@ impl<T, const N: usize> FixedVec<T, N> {
Ok(())
}

pub(crate) fn pop(&mut self) -> Option<T> {
/// Pop the last element in the fixed vector.
pub fn pop(&mut self) -> Option<T> {
if self.len == 0 {
return None;
}
Expand Down Expand Up @@ -148,7 +153,8 @@ pub struct FixedString<const N: usize> {
}

impl<const N: usize> FixedString<N> {
pub(crate) const fn new() -> FixedString<N> {
/// Construct a new fixed string.
pub const fn new() -> FixedString<N> {
FixedString {
data: FixedVec::new(),
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
//! Trait used to govern allocations.
//! Trait used to handle individual buffer allocations.
//! [<img alt="github" src="https://img.shields.io/badge/github-udoprog/musli-8da0cb?style=for-the-badge&logo=github" height="20">](https://github.com/udoprog/musli)
//! [<img alt="crates.io" src="https://img.shields.io/crates/v/musli-allocator.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/musli-allocator)
//! [<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-musli--allocator-66c2a5?style=for-the-badge&logoColor=white&logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDUxMiA1MTIiPjxwYXRoIGZpbGw9IiNmNWY1ZjUiIGQ9Ik00ODguNiAyNTAuMkwzOTIgMjE0VjEwNS41YzAtMTUtOS4zLTI4LjQtMjMuNC0zMy43bC0xMDAtMzcuNWMtOC4xLTMuMS0xNy4xLTMuMS0yNS4zIDBsLTEwMCAzNy41Yy0xNC4xIDUuMy0yMy40IDE4LjctMjMuNCAzMy43VjIxNGwtOTYuNiAzNi4yQzkuMyAyNTUuNSAwIDI2OC45IDAgMjgzLjlWMzk0YzAgMTMuNiA3LjcgMjYuMSAxOS45IDMyLjJsMTAwIDUwYzEwLjEgNS4xIDIyLjEgNS4xIDMyLjIgMGwxMDMuOS01MiAxMDMuOSA1MmMxMC4xIDUuMSAyMi4xIDUuMSAzMi4yIDBsMTAwLTUwYzEyLjItNi4xIDE5LjktMTguNiAxOS45LTMyLjJWMjgzLjljMC0xNS05LjMtMjguNC0yMy40LTMzLjd6TTM1OCAyMTQuOGwtODUgMzEuOXYtNjguMmw4NS0zN3Y3My4zek0xNTQgMTA0LjFsMTAyLTM4LjIgMTAyIDM4LjJ2LjZsLTEwMiA0MS40LTEwMi00MS40di0uNnptODQgMjkxLjFsLTg1IDQyLjV2LTc5LjFsODUtMzguOHY3NS40em0wLTExMmwtMTAyIDQxLjQtMTAyLTQxLjR2LS42bDEwMi0zOC4yIDEwMiAzOC4ydi42em0yNDAgMTEybC04NSA0Mi41di03OS4xbDg1LTM4Ljh2NzUuNHptMC0xMTJsLTEwMiA0MS40LTEwMi00MS40di0uNmwxMDItMzguMiAxMDIgMzguMnYuNnoiPjwvcGF0aD48L3N2Zz4K" height="20">](https://docs.rs/musli-allocator)
//!
//! Allocation support for [Müsli].
//!
//! This crate contains two types of allocators:
//! * The [`System`] allocator, which uses the system allocation facilities.
//! Particularly [`std::alloc::System`].
//! * The [`Stack`] allocator, which can allocate buffers from a fixed-size
//! slice.
//!
//! [Müsli]: <https://docs.rs/musli>
//! [`std::alloc::System`]: https://doc.rust-lang.org/std/alloc/struct.System.html

#![allow(clippy::type_complexity)]
#![deny(missing_docs)]
#![no_std]

#[cfg_attr(test, macro_use)]
#[cfg(feature = "std")]
extern crate std;

#[cfg(feature = "alloc")]
extern crate alloc;

#[cfg(test)]
mod tests;
Expand All @@ -12,9 +35,13 @@ pub use self::system::{System, SystemBuffer};
mod disabled;
pub use self::disabled::Disabled;

mod stack;
pub mod stack;
pub use self::stack::{Stack, StackBuffer};

mod fixed;
#[doc(hidden)]
pub use self::fixed::{FixedString, FixedVec};

#[cfg(feature = "alloc")]
mod default_alloc {
#![allow(missing_docs)]
Expand Down Expand Up @@ -109,11 +136,11 @@ use musli::context::Buf;
/// # Examples
///
/// ```
/// use musli_common::allocator::{self, Allocator};
/// use musli_allocator::Allocator;
/// use musli::context::Buf;
///
/// let mut buf = allocator::buffer();
/// let alloc = allocator::new(&mut buf);
/// let mut buf = musli_allocator::buffer();
/// let alloc = musli_allocator::new(&mut buf);
///
/// let mut a = alloc.alloc().expect("allocation a failed");
/// let mut b = alloc.alloc().expect("allocation b failed");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,16 @@ use core::slice;

use musli::context::Buf;

use crate::allocator::Allocator;
use crate::fixed::FixedVec;
use crate::{Allocator, FixedVec};

const HEADER_U32: u32 = size_of::<Header>() as u32;
// We keep max bytes to 2^31, since that ensures that addition between two
// magnitutes never overflow.
const MAX_BYTES: u32 = i32::MAX as u32;

/// A buffer that can be used to store data on the stack.
///
/// See the [module level documentation][self] for more information.
pub struct StackBuffer<const C: usize> {
data: FixedVec<u8, C>,
}
Expand Down Expand Up @@ -125,6 +126,8 @@ impl<const C: usize> DerefMut for StackBuffer<C> {
/// in.
///
/// To conveniently construct a buffer you can use the [`StackBuffer`] type.
///
/// See the [module level documentation][self] for more information.
pub struct Stack<'a> {
// This must be an unsafe cell, since it's mutably accessed through an
// immutable pointers. We simply make sure that those accesses do not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::fmt::{self, Write};
use std::string::String;
use std::vec::Vec;

use crate::allocator::{Allocator, Buf, Stack, StackBuffer};
use musli::context::Buf;

use crate::{Allocator, Stack, StackBuffer};

use super::{Header, HeaderId, State};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use alloc::vec::Vec;

use musli::context::Buf;

use crate::allocator::Allocator;
use crate::Allocator;

/// A dynamic buffer allocated on the heap.
pub struct SystemBuffer {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::allocator::Allocator;
use crate::Allocator;
use musli::context::Buf;

fn basic_allocations<A: Allocator>(alloc: &A) {
Expand Down Expand Up @@ -31,14 +31,14 @@ fn basic_allocations<A: Allocator>(alloc: &A) {

#[test]
fn alloc_basic() {
let mut buf = crate::allocator::SystemBuffer::new();
let alloc = crate::allocator::System::new(&mut buf);
let mut buf = crate::SystemBuffer::new();
let alloc = crate::System::new(&mut buf);
basic_allocations(&alloc);
}

#[test]
fn nostd_basic() {
let mut buf = crate::allocator::StackBuffer::<4096>::new();
let alloc = crate::allocator::Stack::new(&mut buf);
let mut buf = crate::StackBuffer::<4096>::new();
let alloc = crate::Stack::new(&mut buf);
basic_allocations(&alloc);
}
7 changes: 4 additions & 3 deletions crates/musli-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std"]
std = ["musli/std", "simdutf8?/std"]
alloc = []
std = ["alloc", "musli/std", "simdutf8?/std", "musli-allocator/std"]
alloc = ["musli-allocator/alloc"]

[dependencies]
musli = { path = "../musli", version = "0.0.96", default-features = false }
musli-allocator = { path = "../musli-allocator", version = "0.0.96", default-features = false }
simdutf8 = { version = "0.1.4", optional = true, default-features = false }

[dev-dependencies]
Expand Down
3 changes: 1 addition & 2 deletions crates/musli-common/src/context/no_std_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ use core::ops::Range;
use musli::context::Error;
use musli::Context;

use crate::allocator::Allocator;
use crate::allocator::{Allocator, FixedString, FixedVec};
use crate::context::rich_error::{RichError, Step};
use crate::fixed::{FixedString, FixedVec};

use super::access::{Access, Shared};

Expand Down
5 changes: 3 additions & 2 deletions crates/musli-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ extern crate std;
#[cfg(feature = "alloc")]
extern crate alloc;

pub mod allocator;
#[doc(inline)]
pub use musli_allocator as allocator;

pub mod buffered_writer;
pub mod context;
mod fixed;
pub mod fixed_bytes;
pub mod int;
#[macro_use]
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-descriptive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std", "simdutf8"]
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-json/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std", "simdutf8", "musli-value", "parse-full"]
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[lib]
proc-macro = true
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-storage/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std", "simdutf8"]
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-value/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std"]
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-wire/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std", "simdutf8"]
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-zerocopy-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization", "zerocopy"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[lib]
proc-macro = true
Expand Down
2 changes: 1 addition & 1 deletion crates/musli-zerocopy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization", "zerocopy"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std"]
Expand Down
2 changes: 1 addition & 1 deletion crates/musli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ homepage = "https://github.com/udoprog/musli"
repository = "https://github.com/udoprog/musli"
license = "MIT OR Apache-2.0"
keywords = ["no_std", "serialization"]
categories = ["encoding"]
categories = ["no-std", "encoding"]

[features]
default = ["std"]
Expand Down

0 comments on commit dbae2cf

Please sign in to comment.