diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2017-12-03 13:49:46 +0100 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-04-15 20:53:03 +0200 |
| commit | 19d44f2d2491cc2c5f603da79737dacac84715ef (patch) | |
| tree | a818f8b92ac8a2eef64ec671600b0ee02f9fabe7 /src/libarena | |
| parent | ead5cf11b81e97b614f57ed4cece67e9453b9ced (diff) | |
| download | rust-19d44f2d2491cc2c5f603da79737dacac84715ef.tar.gz rust-19d44f2d2491cc2c5f603da79737dacac84715ef.zip | |
Make arenas thread safe
Diffstat (limited to 'src/libarena')
| -rw-r--r-- | src/libarena/Cargo.toml | 3 | ||||
| -rw-r--r-- | src/libarena/lib.rs | 71 |
2 files changed, 74 insertions, 0 deletions
diff --git a/src/libarena/Cargo.toml b/src/libarena/Cargo.toml index b53c0a2f48b..e2af67dd928 100644 --- a/src/libarena/Cargo.toml +++ b/src/libarena/Cargo.toml @@ -7,3 +7,6 @@ version = "0.0.0" name = "arena" path = "lib.rs" crate-type = ["dylib"] + +[dependencies] +rustc_data_structures = { path = "../librustc_data_structures" } \ No newline at end of file diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index b319f333342..c79e0e14e3d 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -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; |
