Skip to content

Commit d3d3e4a

Browse files
committed
revamp to include stdalloc
1 parent 25921f1 commit d3d3e4a

File tree

14 files changed

+810
-122
lines changed

14 files changed

+810
-122
lines changed

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@ name = "example"
1616

1717
[features]
1818
unsafe = []
19-
no-stdlib = []

alloc-stdlib/Cargo.toml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "alloc-stdlib"
3+
description = "A dynamic allocator example that may be used with the stdlib"
4+
version = "0.1.0"
5+
authors = ["Daniel Reiter Horn <[email protected]>"]
6+
documentation = "https://raw.githubusercontent.com/dropbox/rust-alloc-no-stdlib/master/alloc-stdlib/tests/lib.rs"
7+
homepage = "https://github.com/dropbox/rust-alloc-no-stdlib"
8+
readme = "README.md"
9+
keywords = ["custom", "allocator", "calloc", "safe", "nostd"]
10+
license = "BSD-3-Clause"
11+
repository = "https://github.com/dropbox/rust-alloc-no-stdlib"
12+
autobins = false
13+
14+
[[bin]]
15+
name = "example"
16+
17+
[dependencies]
18+
"alloc-no-stdlib" = "~1"
19+
20+
[features]
21+
unsafe = []

alloc-stdlib/src/bin/example.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
//#![feature(trace_macros)]
2+
extern crate alloc_stdlib;
3+
#[macro_use]
4+
extern crate alloc_no_stdlib;
5+
6+
extern crate core;
7+
use core::ops;
8+
9+
pub use alloc_stdlib::{HeapAlloc, StandardAlloc};
10+
use alloc_stdlib::HeapPrealloc;
11+
mod tests;
12+
extern {
13+
fn calloc(n_elem : usize, el_size : usize) -> *mut u8;
14+
}
15+
extern {
16+
fn free(ptr : *mut u8);
17+
}
18+
19+
20+
//use alloc::AllocatedSlice;
21+
use alloc_no_stdlib::SliceWrapper;
22+
use alloc_no_stdlib::SliceWrapperMut;
23+
use alloc_no_stdlib::AllocatedStackMemory;
24+
use alloc_no_stdlib::Allocator;
25+
use alloc_no_stdlib::StackAllocator;
26+
27+
use alloc_no_stdlib::bzero;
28+
declare_stack_allocator_struct!(CallocAllocatedFreelist4, 4, calloc);
29+
declare_stack_allocator_struct!(StackAllocatedFreelist16, 16, stack);
30+
31+
fn show_heap_prealloc() {
32+
let mut zero_global_buffer = define_allocator_memory_pool!(4, u8, [0; 1024 * 1024 * 20], heap);
33+
34+
let mut boxallocator = HeapPrealloc::<u8>::new_allocator(1024 * 1024, &mut zero_global_buffer, bzero);
35+
36+
{
37+
let mut x = boxallocator.alloc_cell(9999);
38+
x.slice_mut()[0] = 3;
39+
let mut y = boxallocator.alloc_cell(4);
40+
y[0] = 5;
41+
boxallocator.free_cell(y);
42+
43+
let mut three = boxallocator.alloc_cell(3);
44+
three[0] = 6;
45+
boxallocator.free_cell(three);
46+
47+
let mut z = boxallocator.alloc_cell(4);
48+
z.slice_mut()[1] = 8;
49+
let mut reget_three = boxallocator.alloc_cell(4);
50+
reget_three.slice_mut()[1] = 9;
51+
//y.mem[0] = 6; // <-- this is an error (use after free)
52+
println!("x[0] = {:?} z[0] = {:?} z[1] = {:?} r3[0] = {:?} r3[1] = {:?}", x.mem[0], z.mem[0], z.mem[1], reget_three[0], reget_three.slice()[1]);
53+
let mut _z = boxallocator.alloc_cell(1);
54+
}
55+
}
56+
57+
fn main() {
58+
let mut global_buffer = unsafe {define_allocator_memory_pool!(4, u8, [0; 1024 * 1024 * 200], calloc)};
59+
{
60+
let gbref = &mut global_buffer;
61+
{
62+
let mut ags = CallocAllocatedFreelist4::<u8>::new_allocator(gbref.data, bzero);
63+
64+
{
65+
let mut x = ags.alloc_cell(9999);
66+
x.slice_mut()[0] = 4;
67+
let mut y = ags.alloc_cell(4);
68+
y[0] = 5;
69+
ags.free_cell(y);
70+
71+
let mut three = ags.alloc_cell(3);
72+
three[0] = 6;
73+
ags.free_cell(three);
74+
75+
let mut z = ags.alloc_cell(4);
76+
z.slice_mut()[1] = 8;
77+
let mut reget_three = ags.alloc_cell(4);
78+
reget_three.slice_mut()[1] = 9;
79+
//y.mem[0] = 6; // <-- this is an error (use after free)
80+
println!("x[0] = {:?} z[0] = {:?} z[1] = {:?} r3[0] = {:?} r3[1] = {:?}", x.mem[0], z.mem[0], z.mem[1], reget_three[0], reget_three.slice()[1]);
81+
let mut _z = ags.alloc_cell(1);
82+
}
83+
}
84+
}
85+
86+
87+
let mut stack_global_buffer = define_allocator_memory_pool!(16, u8, [0; 1024 * 1024], stack);
88+
let mut stackallocator = StackAllocatedFreelist16::<u8>::new_allocator(&mut stack_global_buffer, bzero);
89+
{
90+
let mut x = stackallocator.alloc_cell(9999);
91+
x.slice_mut()[0] = 3;
92+
let mut y = stackallocator.alloc_cell(4);
93+
y[0] = 5;
94+
stackallocator.free_cell(y);
95+
96+
let mut three = stackallocator.alloc_cell(3);
97+
three[0] = 6;
98+
stackallocator.free_cell(three);
99+
100+
let mut z = stackallocator.alloc_cell(4);
101+
z.slice_mut()[1] = 8;
102+
let mut reget_three = stackallocator.alloc_cell(4);
103+
reget_three.slice_mut()[1] = 9;
104+
//y.mem[0] = 6; // <-- this is an error (use after free)
105+
println!("x[0] = {:?} z[0] = {:?} z[1] = {:?} r3[0] = {:?} r3[1] = {:?}", x.mem[0], z.mem[0], z.mem[1], reget_three[0], reget_three.slice()[1]);
106+
let mut _z = stackallocator.alloc_cell(1);
107+
}
108+
109+
let mut halloc = HeapAlloc::<u8>::default();
110+
for _i in 1..10 { // heap test
111+
let mut x = halloc.alloc_cell(100000);
112+
x.slice_mut()[0] = 4;
113+
let mut y = halloc.alloc_cell(110000);
114+
y.slice_mut()[0] = 5;
115+
let mut z = halloc.alloc_cell(120000);
116+
z.slice_mut()[0] = 6;
117+
halloc.free_cell(y);
118+
println!("x[0] {:?} x[9] {:?} y[0] {:?} z[0] {:?}",
119+
x.slice()[0], x.slice()[9], -999, z.slice()[0]);
120+
}
121+
show_heap_prealloc();
122+
}

alloc-stdlib/src/bin/tests.rs

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#![allow(unused_imports)]
2+
#[cfg(test)]
3+
extern crate core;
4+
use alloc_no_stdlib::{Allocator, SliceWrapper, SliceWrapperMut};
5+
use super::{HeapAlloc, StandardAlloc};
6+
#[cfg(feature="unsafe")]
7+
use alloc_stdlib::HeapAllocUninitialized;
8+
#[test]
9+
fn heap_test() {
10+
let mut halloc : HeapAlloc<u8> = HeapAlloc::<u8>{default_value: 0};
11+
for _i in 1..10 { // heap test
12+
let mut x = halloc.alloc_cell(100000);
13+
x.slice_mut()[0] = 4;
14+
let mut y = halloc.alloc_cell(110000);
15+
y.slice_mut()[0] = 5;
16+
let mut z = halloc.alloc_cell(120000);
17+
z.slice_mut()[0] = 6;
18+
assert_eq!(y.slice()[0], 5);
19+
halloc.free_cell(y);
20+
assert_eq!(x.slice()[0], 4);
21+
assert_eq!(x.slice()[9], 0);
22+
assert_eq!(z.slice()[0], 6);
23+
}
24+
25+
}
26+
27+
#[test]
28+
fn std_test() {
29+
let mut halloc = StandardAlloc::default();
30+
for _i in 1..10 { // heap test
31+
let mut x = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut halloc, 100000);
32+
x.slice_mut()[0] = 4;
33+
let mut y = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut halloc, 110000);
34+
y.slice_mut()[0] = 5;
35+
let mut z = <StandardAlloc as Allocator<u8>>::alloc_cell(&mut halloc, 120000);
36+
z.slice_mut()[0] = 6;
37+
assert_eq!(y.slice()[0], 5);
38+
halloc.free_cell(y);
39+
assert_eq!(x.slice()[0], 4);
40+
assert_eq!(x.slice()[9], 0);
41+
assert_eq!(z.slice()[0], 6);
42+
}
43+
44+
}
45+
46+
47+
#[cfg(feature="unsafe")]
48+
#[test]
49+
fn std_unsafe_heap_test() {
50+
let mut halloc = unsafe{HeapAllocUninitialized::<u8>::new()};
51+
for _i in 1..10 { // heap test
52+
let mut x = halloc.alloc_cell(100000);
53+
x.slice_mut()[0] = 4;
54+
let mut y = halloc.alloc_cell(110000);
55+
y.slice_mut()[0] = 5;
56+
let mut z = halloc.alloc_cell(120000);
57+
z.slice_mut()[0] = 6;
58+
assert_eq!(y.slice()[0], 5);
59+
halloc.free_cell(y);
60+
assert_eq!(x.slice()[0], 4);
61+
assert_eq!(x.slice()[9], 0);
62+
assert_eq!(z.slice()[0], 6);
63+
}
64+
65+
}
66+
67+
#[cfg(feature="stdlib")]
68+
#[test]
69+
fn std_heap_test() {
70+
let mut halloc = HeapAlloc::<u8>::new(0);
71+
for _i in 1..10 { // heap test
72+
let mut x = halloc.alloc_cell(100000);
73+
x.slice_mut()[0] = 4;
74+
let mut y = halloc.alloc_cell(110000);
75+
y.slice_mut()[0] = 5;
76+
let mut z = halloc.alloc_cell(120000);
77+
z.slice_mut()[0] = 6;
78+
assert_eq!(y.slice()[0], 5);
79+
halloc.free_cell(y);
80+
assert_eq!(x.slice()[0], 4);
81+
assert_eq!(x.slice()[9], 0);
82+
assert_eq!(z.slice()[0], 6);
83+
}
84+
85+
}

src/heap_alloc.rs renamed to alloc-stdlib/src/heap_alloc.rs

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,54 @@ use std;
44

55
use super::{SliceWrapper, SliceWrapperMut, Allocator};
66

7-
use core;
8-
use core::ops;
7+
use std::ops;
98
use std::boxed::Box;
109
use std::vec::Vec;
11-
pub struct WrapBox<T> {
12-
b : std::boxed::Box<[T]>,
10+
pub struct WrapBox<T>(std::boxed::Box<[T]>);
11+
12+
impl<T> From<Vec<T>> for WrapBox<T> {
13+
fn from(data: Vec<T>) -> Self {
14+
WrapBox(data.into())
15+
}
16+
}
17+
18+
impl<T> Into<Box<[T]>> for WrapBox<T> {
19+
fn into(self) -> Box<[T]> {
20+
self.0
21+
}
1322
}
1423

15-
impl<T> core::default::Default for WrapBox<T> {
24+
impl<T> Default for WrapBox<T> {
1625
fn default() -> Self {
1726
let v : std::vec::Vec<T> = std::vec::Vec::new();
1827
let b = v.into_boxed_slice();
19-
return WrapBox::<T>{b : b};
28+
return WrapBox::<T>(b);
2029
}
2130
}
22-
define_index_ops_mut!(T, WrapBox<T>);
2331

2432
impl<T> super::SliceWrapper<T> for WrapBox<T> {
2533
fn slice(&self) -> & [T] {
26-
return &*self.b
34+
return &*self.0
2735
}
2836
}
2937

3038
impl<T> super::SliceWrapperMut<T> for WrapBox<T> {
3139
fn slice_mut(&mut self) -> &mut [T] {
32-
return &mut*self.b
40+
return &mut*self.0
3341
}
3442
}
3543

3644
pub struct HeapAlloc<T : core::clone::Clone>{
3745
pub default_value : T,
3846
}
39-
impl<T : core::clone::Clone> HeapAlloc<T> {
47+
48+
impl<T: Clone+Default> Default for HeapAlloc<T> {
49+
fn default() -> Self {
50+
Self::new(T::default())
51+
}
52+
}
53+
54+
impl<T : Clone> HeapAlloc<T> {
4055
pub fn new(data : T) -> HeapAlloc<T> {
4156
return HeapAlloc::<T>{default_value : data};
4257
}
@@ -48,7 +63,7 @@ impl<T : core::clone::Clone> super::Allocator<T> for HeapAlloc<T> {
4863

4964
let v : std::vec::Vec<T> = vec![self.default_value.clone();len];
5065
let b = v.into_boxed_slice();
51-
return WrapBox::<T>{b : b};
66+
return WrapBox::<T>(b);
5267
}
5368
fn free_cell(self : &mut HeapAlloc<T>, _data : WrapBox<T>) {
5469

alloc-stdlib/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#[macro_use]
2+
extern crate alloc_no_stdlib;
3+
pub mod heap_alloc;
4+
pub mod std_alloc;
5+
pub use self::heap_alloc::{HeapAlloc, HeapPrealloc};
6+
pub use self::std_alloc::{StandardAlloc};
7+
pub use alloc_no_stdlib::{Allocator, SliceWrapper, SliceWrapperMut};
8+
pub use alloc_no_stdlib::{StackAllocator, AllocatedStackMemory};
9+
#[cfg(feature="unsafe")]
10+
pub use heap_alloc::HeapAllocUninitialized;

alloc-stdlib/src/std_alloc.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
use super::heap_alloc::WrapBox;
2+
use super::{Allocator};
3+
#[derive(Default, Clone, Copy, Debug)]
4+
pub struct StandardAlloc{}
5+
6+
impl<T: Clone+Default> Allocator<T> for StandardAlloc {
7+
type AllocatedMemory = WrapBox<T>;
8+
fn alloc_cell(&mut self, len : usize) -> WrapBox<T> {
9+
vec![T::default().clone();len].into()
10+
}
11+
fn free_cell(&mut self, _data : WrapBox<T>) {
12+
13+
}
14+
}
File renamed without changes.

0 commit comments

Comments
 (0)