Skip to content

Commit 1f08803

Browse files
committed
added store
1 parent ba1d610 commit 1f08803

File tree

3 files changed

+313
-2
lines changed

3 files changed

+313
-2
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "malloc-array"
33
description = "libc heap array allocator"
4-
version = "1.3.3"
4+
version = "1.4.3"
55
authors = ["Avril <flanchan@cumallover.me>"]
66
edition = "2018"
77
license = "GPL-3.0-or-later"

src/lib.rs

+65-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,17 @@ extern crate jemalloc_sys;
99
mod tests {
1010
use super::*;
1111

12+
#[test]
13+
fn from_bytes()
14+
{
15+
unsafe {
16+
let heap = HeapArray::<i32>::from_bytes(&[0xff,0xff,0xff,0xff,0,0,0,0,0xff,0xff,0xff,0xff]);
17+
assert_eq!(heap[0], -1);
18+
assert_eq!(heap[1], 0);
19+
assert_eq!(heap[2], -1);
20+
}
21+
}
22+
1223
#[test]
1324
fn copy() {
1425
let heap = heap![unsafe 1u16; 10];
@@ -179,6 +190,7 @@ mod alloc;
179190
mod reinterpret;
180191
pub mod init;
181192
pub use init::InitIterExt;
193+
pub mod store;
182194

183195
use std::{
184196
ops::{
@@ -201,6 +213,7 @@ use std::{
201213
use crate::{
202214
ptr::{
203215
VoidPointer,
216+
ConstVoidPointer,
204217
},
205218
};
206219

@@ -604,11 +617,37 @@ impl<T> HeapArray<T>
604617
}
605618
}
606619

620+
/// Copy memory in from a slice of bytes.
621+
pub unsafe fn memory_from_bytes<U: AsRef<[u8]>>(&mut self, from: U) -> usize
622+
{
623+
let from = from.as_ref();
624+
let size = std::cmp::min(from.len(), self.len_bytes());
625+
ptr::memcpy(self.ptr as VoidPointer, &from[0] as *const u8 as ConstVoidPointer, size);
626+
size
627+
}
628+
629+
/// Copy memory in from a pointer to bytes.
630+
pub unsafe fn memory_from_raw_bytes(&mut self, from: *const u8, size: usize) -> usize
631+
{
632+
let size = std::cmp::min(size, self.len_bytes());
633+
ptr::memcpy(self.ptr as VoidPointer, from as *const u8 as ConstVoidPointer, size);
634+
size
635+
}
636+
637+
/// Copy memory in from a raw pointer.
638+
pub unsafe fn memory_from_slice<U: AsRef<[T]>>(&mut self, from: U) -> usize
639+
{
640+
let from = from.as_ref();
641+
let size = std::cmp::min(from.len(), self.len());
642+
ptr::memcpy(self.ptr as VoidPointer, &from[0] as *const T as ConstVoidPointer, size * std::mem::size_of::<T>());
643+
size
644+
}
645+
607646
/// Copy memory in from a raw pointer.
608647
pub unsafe fn memory_from_raw(&mut self, from: *const T, size: usize) -> usize
609648
{
610649
let size = std::cmp::min(size, self.len());
611-
ptr::memcpy(self.ptr as VoidPointer, from as VoidPointer, size * std::mem::size_of::<T>());
650+
ptr::memcpy(self.ptr as VoidPointer, from as *const T as ConstVoidPointer, size * std::mem::size_of::<T>());
612651
size
613652
}
614653

@@ -619,6 +658,31 @@ impl<T> HeapArray<T>
619658
inp.memory_from_raw(from, size);
620659
inp
621660
}
661+
662+
/// Create a new instance with memory copied from a slice.
663+
pub unsafe fn from_slice_copied<U: AsRef<[T]>>(from: U) -> Self
664+
where T: Copy
665+
{
666+
let from = from.as_ref();
667+
Self::from_raw_copied(&from[0] as *const T, from.len())
668+
}
669+
670+
/// Create a new instance with memory bytes copied from a raw pointer.
671+
pub unsafe fn from_raw_bytes(from: *const u8, size: usize) -> Self
672+
{
673+
assert_eq!(size % Self::element_size(),0,"Cannot fit T into this size.");
674+
675+
let mut inp = Self::new_uninit(size / Self::element_size());
676+
inp.memory_from_raw_bytes(from, size);
677+
inp
678+
}
679+
680+
/// Create a new instance with memory bytes copied from a slice.
681+
pub unsafe fn from_bytes<U: AsRef<[u8]>>(from: U) -> Self
682+
{
683+
let from = from.as_ref();
684+
Self::from_raw_bytes(&from[0], from.len())
685+
}
622686
}
623687

624688
impl<T, I> Index<I> for HeapArray<T>

src/store.rs

+247
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
use crate::*;
2+
3+
/// Statically typed pointer store. `free()`s and drops on drop.
4+
#[derive(Debug)]
5+
pub struct Store<T>
6+
{
7+
pointers: Vec<*mut T>,
8+
}
9+
10+
#[cfg(test)]
11+
mod tests
12+
{
13+
use super::*;
14+
#[test]
15+
fn store()
16+
{
17+
let mut store = Store::new();
18+
unsafe {
19+
for _a in 0..10 {
20+
let _ptr = store.ptr(alloc::malloc(100).unwrap());
21+
}
22+
}
23+
}
24+
#[test]
25+
fn dyn_store()
26+
{
27+
let mut store = DynStore::new();
28+
unsafe {
29+
for _a in 0..10 {
30+
let ptr = store.ptr(alloc::malloc(4).unwrap() as *mut u32);
31+
*ptr = 100u32;
32+
}
33+
}
34+
35+
}
36+
#[test]
37+
fn into_ha()
38+
{
39+
let mut store = Store::new();
40+
unsafe {
41+
for a in 0..10 {
42+
*store.ptr(alloc::malloc(4).unwrap() as *mut u32) = a;
43+
}
44+
}
45+
let ha = store.into_heap_array();
46+
assert_eq!(ha.len(), 10);
47+
assert_eq!(&ha[..], &[0,1,2,3,4,5,6,7,8,9]);
48+
}
49+
}
50+
51+
impl<T> Store<T>
52+
{
53+
/// Create a new pointer store.
54+
pub fn new() -> Self
55+
{
56+
Self{pointers:Vec::new()}
57+
}
58+
59+
/// Add a pointer to the store.
60+
pub fn ptr(&mut self, ptr: *mut T) -> *mut T
61+
{
62+
self.pointers.push(ptr);
63+
ptr
64+
}
65+
66+
/// Remove a pointer from the store.
67+
pub fn remove(&mut self, ptr: *mut T)
68+
{
69+
while let Some(i) = self.pointers.iter().position(|x| *x == ptr)
70+
{
71+
self.pointers.remove(i);
72+
}
73+
}
74+
75+
/// Consumes the instance and returns the pointers without freeing them.
76+
pub fn into_raw_parts(mut self) -> Vec<*mut T>
77+
{
78+
std::mem::replace(&mut self.pointers, Vec::new())
79+
}
80+
81+
/// Consume a vector of pointers and return a new `Store<T>`.
82+
pub fn from_raw_parts(pointers: Vec<*mut T>) -> Self
83+
{
84+
Self {
85+
pointers,
86+
}
87+
}
88+
89+
/// Free all the pointers in the store without calling their destructors (if the have any).
90+
pub fn free(mut self)
91+
{
92+
for &mut x in self.pointers.iter_mut()
93+
{
94+
unsafe {
95+
alloc::free(x as VoidPointer);
96+
}
97+
}
98+
self.pointers.clear()
99+
}
100+
101+
/// Move all data from all pointers into a new `HeapArray<T>` instance and free the old pointers.
102+
pub fn into_heap_array(mut self) -> HeapArray<T>
103+
{
104+
let mut output = heap![T; self.pointers.len()];
105+
for (mut init, old) in output.initialise().zip(std::mem::replace(&mut self.pointers, Vec::new()).into_iter())
106+
{
107+
unsafe {
108+
init.put(ptr::take(old));
109+
alloc::free(old as *mut ());
110+
}
111+
}
112+
output
113+
}
114+
}
115+
116+
impl<T> std::ops::Drop for Store<T>
117+
{
118+
fn drop(&mut self)
119+
{
120+
for &mut ptr in self.pointers.iter_mut()
121+
{
122+
unsafe {
123+
drop(ptr::take(ptr));
124+
alloc::free(ptr as VoidPointer);
125+
}
126+
}
127+
self.pointers.clear();
128+
}
129+
}
130+
131+
/// Dynamically typed pointer store. Frees on drop.
132+
#[derive(Debug)]
133+
pub struct DynStore
134+
{
135+
pointers: Vec<VoidPointer>,
136+
}
137+
138+
impl DynStore
139+
{
140+
/// Create a new pointer store.
141+
pub fn new() -> Self
142+
{
143+
Self{pointers:Vec::new()}
144+
}
145+
146+
/// Add a pointer to the store.
147+
pub fn ptr<T>(&mut self, ptr: *mut T) -> *mut T
148+
{
149+
self.pointers.push(ptr as VoidPointer);
150+
ptr
151+
}
152+
153+
/// Remove a pointer from the store.
154+
pub fn remove<T>(&mut self, ptr: *mut T)
155+
{
156+
while let Some(i) = self.pointers.iter().position(|x| *x == ptr as VoidPointer)
157+
{
158+
self.pointers.remove(i);
159+
}
160+
}
161+
162+
/// Consumes the instance and returns the pointers without freeing them.
163+
pub fn into_raw_parts(mut self) -> Vec<*mut ()>
164+
{
165+
std::mem::replace(&mut self.pointers, Vec::new())
166+
}
167+
168+
/// Consume a vector of pointers and return a new `Store<T>`.
169+
pub fn from_raw_parts(pointers: Vec<*mut ()>) -> Self
170+
{
171+
Self {
172+
pointers,
173+
}
174+
}
175+
176+
177+
/// Free all the pointers in the store without calling their destructors (if the have any).
178+
pub fn free(mut self)
179+
{
180+
for &mut x in self.pointers.iter_mut()
181+
{
182+
unsafe {
183+
alloc::free(x);
184+
}
185+
}
186+
self.pointers.clear()
187+
}
188+
189+
}
190+
191+
impl std::ops::Drop for DynStore
192+
{
193+
fn drop(&mut self)
194+
{
195+
for &mut ptr in self.pointers.iter_mut()
196+
{
197+
unsafe {
198+
drop(ptr::take(ptr));
199+
alloc::free(ptr);
200+
}
201+
}
202+
self.pointers.clear();
203+
}
204+
}
205+
206+
impl<T> IntoIterator for Store<T>
207+
{
208+
type Item = *mut T;
209+
type IntoIter = std::vec::IntoIter<Self::Item>;
210+
211+
fn into_iter(mut self) -> Self::IntoIter
212+
{
213+
std::mem::replace(&mut self.pointers, Vec::new()).into_iter()
214+
}
215+
}
216+
217+
impl IntoIterator for DynStore
218+
{
219+
type Item = *mut ();
220+
type IntoIter = std::vec::IntoIter<Self::Item>;
221+
222+
fn into_iter(mut self) -> Self::IntoIter
223+
{
224+
std::mem::replace(&mut self.pointers, Vec::new()).into_iter()
225+
}
226+
}
227+
228+
use std::iter::FromIterator;
229+
impl<T> FromIterator<*mut T> for Store<T>
230+
{
231+
fn from_iter<I: IntoIterator<Item=*mut T>>(iter: I) -> Self
232+
{
233+
Self {
234+
pointers: Vec::from_iter(iter)
235+
}
236+
}
237+
}
238+
239+
impl<T> FromIterator<*mut T> for DynStore
240+
{
241+
fn from_iter<I: IntoIterator<Item=*mut T>>(iter: I) -> Self
242+
{
243+
Self {
244+
pointers: Vec::from_iter(iter.into_iter().map(|x| x as *mut ()))
245+
}
246+
}
247+
}

0 commit comments

Comments
 (0)