Make arenas thread safe
This commit is contained in:
parent
ead5cf11b8
commit
19d44f2d24
|
@ -66,6 +66,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[[package]]
|
||||
name = "arena"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"rustc_data_structures 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
|
|
|
@ -7,3 +7,6 @@ version = "0.0.0"
|
|||
name = "arena"
|
||||
path = "lib.rs"
|
||||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
|
@ -32,6 +32,9 @@
|
|||
#![allow(deprecated)]
|
||||
|
||||
extern crate alloc;
|
||||
extern crate rustc_data_structures;
|
||||
|
||||
use rustc_data_structures::sync::MTLock;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cmp;
|
||||
|
@ -290,6 +293,8 @@ pub struct DroplessArena {
|
|||
chunks: RefCell<Vec<TypedArenaChunk<u8>>>,
|
||||
}
|
||||
|
||||
unsafe impl Send for DroplessArena {}
|
||||
|
||||
impl DroplessArena {
|
||||
pub fn new() -> DroplessArena {
|
||||
DroplessArena {
|
||||
|
@ -410,6 +415,72 @@ impl DroplessArena {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct SyncTypedArena<T> {
|
||||
lock: MTLock<TypedArena<T>>,
|
||||
}
|
||||
|
||||
impl<T> SyncTypedArena<T> {
|
||||
#[inline(always)]
|
||||
pub fn new() -> SyncTypedArena<T> {
|
||||
SyncTypedArena {
|
||||
lock: MTLock::new(TypedArena::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn alloc(&self, object: T) -> &mut T {
|
||||
// Extend the lifetime of the result since it's limited to the lock guard
|
||||
unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
// Extend the lifetime of the result since it's limited to the lock guard
|
||||
unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn clear(&mut self) {
|
||||
self.lock.get_mut().clear();
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SyncDroplessArena {
|
||||
lock: MTLock<DroplessArena>,
|
||||
}
|
||||
|
||||
impl SyncDroplessArena {
|
||||
#[inline(always)]
|
||||
pub fn new() -> SyncDroplessArena {
|
||||
SyncDroplessArena {
|
||||
lock: MTLock::new(DroplessArena::new())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
|
||||
self.lock.lock().in_arena(ptr)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn alloc<T>(&self, object: T) -> &mut T {
|
||||
// Extend the lifetime of the result since it's limited to the lock guard
|
||||
unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
|
||||
where
|
||||
T: Copy,
|
||||
{
|
||||
// Extend the lifetime of the result since it's limited to the lock guard
|
||||
unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate test;
|
||||
|
|
Loading…
Reference in New Issue