@@ -31,20 +31,19 @@ limits the program to only a few megs of dynamically allocated data
31
31
32
32
Example:
33
33
34
- ```
35
-
34
+ ``` rust
36
35
// First define a struct to hold all the array on the stack.
37
36
declare_stack_allocator_struct! (StackAllocatedFreelist4 , 4 , stack );
38
37
// since generics cannot be used, the actual struct to hold the memory must be defined with a macro
39
38
...
40
39
41
- // in the code where the memory must be used, first the array needs to be readied
42
- let mut stack_buffer = define_allocator_memory_pool!(4, u8, [0; 65536], stack);
43
- // then an allocator needs to be made and pointed to the stack_buffer on the stack
44
- // the final argument tells the system if free'd data should be zero'd before being
45
- // reused by a subsequent call to alloc_cell
46
- let mut ags = StackAllocatedFreelist4::<u8>::new_allocator(&mut stack_buffer, bzero);
47
- {
40
+ // in the code where the memory must be used, first the array needs to be readied
41
+ let mut stack_buffer = define_allocator_memory_pool! (4 , u8 , [0 ; 65536 ], stack );
42
+ // then an allocator needs to be made and pointed to the stack_buffer on the stack
43
+ // the final argument tells the system if free'd data should be zero'd before being
44
+ // reused by a subsequent call to alloc_cell
45
+ let mut ags = StackAllocatedFreelist4 :: <u8 >:: new_allocator (& mut stack_buffer , bzero );
46
+ {
48
47
// now we can get memory dynamically
49
48
let mut x = ags . alloc_cell (9999 );
50
49
x . slice_mut ()[0 ] = 4 ;
@@ -61,61 +60,64 @@ declare_stack_allocator_struct!(StackAllocatedFreelist4, 4, stack);
61
60
### On the heap
62
61
This uses the standard Box facilities to allocate memory
63
62
64
- let mut halloc = HeapAlloc::<u8 >::new(0);
65
- for _ i in 1..10 { // heap test
66
- let mut x = halloc.alloc_cell(100000);
67
- x[ 0] = 4;
68
- let mut y = halloc.alloc_cell(110000);
69
- y[ 0] = 5;
70
- let mut z = halloc.alloc_cell(120000);
71
- z[ 0] = 6;
72
- assert_eq!(y[ 0] , 5);
73
- halloc.free_cell(y);
74
- assert_eq!(x[ 0] , 4);
75
- assert_eq!(x[ 9] , 0);
76
- assert_eq!(z[ 0] , 6);
77
- }
63
+ ``` rust
64
+ let mut halloc = HeapAlloc :: <u8 >:: new (0 );
65
+ for _i in 1 .. 10 { // heap test
66
+ let mut x = halloc . alloc_cell (100000 );
67
+ x [0 ] = 4 ;
68
+ let mut y = halloc . alloc_cell (110000 );
69
+ y [0 ] = 5 ;
70
+ let mut z = halloc . alloc_cell (120000 );
71
+ z [0 ] = 6 ;
72
+ assert_eq! (y [0 ], 5 );
73
+ halloc . free_cell (y );
74
+ assert_eq! (x [0 ], 4 );
75
+ assert_eq! (x [9 ], 0 );
76
+ assert_eq! (z [0 ], 6 );
77
+ }
78
+ ```
78
79
79
80
### On the heap, but uninitialized
80
81
This does allocate data every time it is requested, but it does not allocate the
81
82
memory, so naturally it is unsafe. The caller must initialize the memory properly
83
+ ``` rust
84
+ let mut halloc = unsafe {HeapAllocUninitialized :: <u8 >:: new ()};
85
+ { // heap test
86
+ let mut x = halloc . alloc_cell (100000 );
87
+ x [0 ] = 4 ;
88
+ let mut y = halloc . alloc_cell (110000 );
89
+ y [0 ] = 5 ;
90
+ let mut z = halloc . alloc_cell (120000 );
91
+ z [0 ] = 6 ;
92
+ assert_eq! (y [0 ], 5 );
93
+ halloc . free_cell (y );
94
+ assert_eq! (x [0 ], 4 );
95
+ assert_eq! (x [9 ], 0 );
96
+ assert_eq! (z [0 ], 6 );
97
+ ...
98
+ }
82
99
```
83
- let mut halloc = unsafe{HeapAllocUninitialized::<u8>::new()};
84
- { // heap test
85
- let mut x = halloc.alloc_cell(100000);
86
- x[0] = 4;
87
- let mut y = halloc.alloc_cell(110000);
88
- y[0] = 5;
89
- let mut z = halloc.alloc_cell(120000);
90
- z[0] = 6;
91
- assert_eq!(y[0], 5);
92
- halloc.free_cell(y);
93
- assert_eq!(x[0], 4);
94
- assert_eq!(x[9], 0);
95
- assert_eq!(z[0], 6);
96
- ...
97
- }
98
100
99
101
100
102
### On the heap in a single pool allocation
101
103
This does a single big allocation on the heap, after which no further usage of the stdlib
102
104
will happen. This can be useful for a jailed application that wishes to restrict syscalls
103
105
at this point
104
106
105
- ```
107
+ ``` rust
106
108
use alloc_no_stdlib :: HeapPrealloc ;
107
109
...
108
- let mut heap_global_buffer = define_allocator_memory_pool!(4096, u8, [ 0; 6 * 1024 * 1024] , heap);
109
- let mut ags = HeapPrealloc::<u8 >::new_allocator(4096, &mut heap_global_buffer, uninitialized);
110
- {
110
+ let mut heap_global_buffer = define_allocator_memory_pool! (4096 , u8 , [0 ; 6 * 1024 * 1024 ], heap );
111
+ let mut ags = HeapPrealloc :: <u8 >:: new_allocator (4096 , & mut heap_global_buffer , uninitialized );
112
+ {
111
113
let mut x = ags . alloc_cell (9999 );
112
114
x . slice_mut ()[0 ] = 4 ;
113
115
let mut y = ags . alloc_cell (4 );
114
116
y [0 ] = 5 ;
115
117
ags . free_cell (y );
116
118
117
119
// y.mem[0] = 6; // <-- this is an error (use after free)
118
- }
120
+ }
119
121
```
120
122
121
123
@@ -126,20 +128,20 @@ will happen. This can be useful for a jailed application that wishes to restrict
126
128
at this point. This option keep does not set the memory to a valid value, so it is
127
129
necessarily marked unsafe
128
130
129
- ```
131
+ ``` rust
130
132
use alloc_no_stdlib :: HeapPrealloc ;
131
133
...
132
- let mut heap_global_buffer = unsafe{HeapPrealloc::<u8 >::new_uninitialized_memory_pool(6 * 1024 * 1024)};
133
- let mut ags = HeapPrealloc::<u8 >::new_allocator(4096, &mut heap_global_buffer, uninitialized);
134
- {
134
+ let mut heap_global_buffer = unsafe {HeapPrealloc :: <u8 >:: new_uninitialized_memory_pool (6 * 1024 * 1024 )};
135
+ let mut ags = HeapPrealloc :: <u8 >:: new_allocator (4096 , & mut heap_global_buffer , uninitialized );
136
+ {
135
137
let mut x = ags . alloc_cell (9999 );
136
138
x . slice_mut ()[0 ] = 4 ;
137
139
let mut y = ags . alloc_cell (4 );
138
140
y [0 ] = 5 ;
139
141
ags . free_cell (y );
140
142
141
143
// y.mem[0] = 6; // <-- this is an error (use after free)
142
- }
144
+ }
143
145
```
144
146
145
147
### With calloc
@@ -148,28 +150,28 @@ It does invoke the C calloc function and hence must invoke unsafe code.
148
150
In this version, the number of cells are fixed to the parameter specified in the struct definition
149
151
(4096 in this example)
150
152
151
- ```
153
+ ``` rust
152
154
extern {
153
- fn calloc(n_elem : usize, el_size : usize) -> * mut u8;
154
- fn malloc(len : usize) -> * mut u8;
155
- fn free(item : * mut u8);
155
+ fn calloc (n_elem : usize , el_size : usize ) -> * mut u8 ;
156
+ fn malloc (len : usize ) -> * mut u8 ;
157
+ fn free (item : * mut u8 );
156
158
}
157
159
158
160
declare_stack_allocator_struct! (CallocAllocatedFreelist4096 , 4096 , calloc );
159
161
...
160
162
161
- // the buffer is defined with 200 megs of zero'd memory from calloc
162
- let mut calloc_global_buffer = unsafe {define_allocator_memory_pool!(4096, u8, [ 0; 200 * 1024 * 1024] , calloc)};
163
- // and assigned to a new_allocator
164
- let mut ags = CallocAllocatedFreelist4096::<u8 >::new_allocator(&mut calloc_global_buffer.data, bzero);
165
- {
163
+ // the buffer is defined with 200 megs of zero'd memory from calloc
164
+ let mut calloc_global_buffer = unsafe {define_allocator_memory_pool! (4096 , u8 , [0 ; 200 * 1024 * 1024 ], calloc )};
165
+ // and assigned to a new_allocator
166
+ let mut ags = CallocAllocatedFreelist4096 :: <u8 >:: new_allocator (& mut calloc_global_buffer . data, bzero );
167
+ {
166
168
let mut x = ags . alloc_cell (9999 );
167
169
x . slice_mut ()[0 ] = 4 ;
168
170
let mut y = ags . alloc_cell (4 );
169
171
y [0 ] = 5 ;
170
172
ags . free_cell (y );
171
173
// y.mem[0] = 6; // <-- this is an error (use after free)
172
- }
174
+ }
173
175
```
174
176
175
177
### With a static, mutable buffer
@@ -185,25 +187,25 @@ If it is used from two places or at different times, undefined behavior may resu
185
187
since multiple allocators may get access to global_buffer.
186
188
187
189
188
- ```
190
+ ``` rust
189
191
declare_stack_allocator_struct! (GlobalAllocatedFreelist , 16 , global );
190
192
define_allocator_memory_pool! (16 , u8 , [0 ; 1024 * 1024 * 100 ], global , global_buffer );
191
193
192
194
...
193
- // this references a global buffer
194
- let mut ags = GlobalAllocatedFreelist::<u8 >::new_allocator(bzero);
195
- unsafe {
196
- bind_global_buffers_to_allocator!(ags, global_buffer, u8);
197
- }
198
- {
195
+ // this references a global buffer
196
+ let mut ags = GlobalAllocatedFreelist :: <u8 >:: new_allocator (bzero );
197
+ unsafe {
198
+ bind_global_buffers_to_allocator! (ags , global_buffer , u8 );
199
+ }
200
+ {
199
201
let mut x = ags . alloc_cell (9999 );
200
202
x . slice_mut ()[0 ] = 4 ;
201
203
let mut y = ags . alloc_cell (4 );
202
204
y [0 ] = 5 ;
203
205
ags . free_cell (y );
204
206
205
207
// y.mem[0] = 6; // <-- this is an error (use after free)
206
- }
208
+ }
207
209
```
208
210
209
211
0 commit comments