Skip to content

Commit 19d44f2

Browse files
committed
Make arenas thread safe
1 parent ead5cf1 commit 19d44f2

File tree

3 files changed

+77
-0
lines changed

3 files changed

+77
-0
lines changed

src/Cargo.lock

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/libarena/Cargo.toml

+3
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,6 @@ version = "0.0.0"
77
name = "arena"
88
path = "lib.rs"
99
crate-type = ["dylib"]
10+
11+
[dependencies]
12+
rustc_data_structures = { path = "../librustc_data_structures" }

src/libarena/lib.rs

+71
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
#![allow(deprecated)]
3333

3434
extern crate alloc;
35+
extern crate rustc_data_structures;
36+
37+
use rustc_data_structures::sync::MTLock;
3538

3639
use std::cell::{Cell, RefCell};
3740
use std::cmp;
@@ -290,6 +293,8 @@ pub struct DroplessArena {
290293
chunks: RefCell<Vec<TypedArenaChunk<u8>>>,
291294
}
292295

296+
unsafe impl Send for DroplessArena {}
297+
293298
impl DroplessArena {
294299
pub fn new() -> DroplessArena {
295300
DroplessArena {
@@ -410,6 +415,72 @@ impl DroplessArena {
410415
}
411416
}
412417

418+
pub struct SyncTypedArena<T> {
419+
lock: MTLock<TypedArena<T>>,
420+
}
421+
422+
impl<T> SyncTypedArena<T> {
423+
#[inline(always)]
424+
pub fn new() -> SyncTypedArena<T> {
425+
SyncTypedArena {
426+
lock: MTLock::new(TypedArena::new())
427+
}
428+
}
429+
430+
#[inline(always)]
431+
pub fn alloc(&self, object: T) -> &mut T {
432+
// Extend the lifetime of the result since it's limited to the lock guard
433+
unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
434+
}
435+
436+
#[inline(always)]
437+
pub fn alloc_slice(&self, slice: &[T]) -> &mut [T]
438+
where
439+
T: Copy,
440+
{
441+
// Extend the lifetime of the result since it's limited to the lock guard
442+
unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
443+
}
444+
445+
#[inline(always)]
446+
pub fn clear(&mut self) {
447+
self.lock.get_mut().clear();
448+
}
449+
}
450+
451+
pub struct SyncDroplessArena {
452+
lock: MTLock<DroplessArena>,
453+
}
454+
455+
impl SyncDroplessArena {
456+
#[inline(always)]
457+
pub fn new() -> SyncDroplessArena {
458+
SyncDroplessArena {
459+
lock: MTLock::new(DroplessArena::new())
460+
}
461+
}
462+
463+
#[inline(always)]
464+
pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
465+
self.lock.lock().in_arena(ptr)
466+
}
467+
468+
#[inline(always)]
469+
pub fn alloc<T>(&self, object: T) -> &mut T {
470+
// Extend the lifetime of the result since it's limited to the lock guard
471+
unsafe { &mut *(self.lock.lock().alloc(object) as *mut T) }
472+
}
473+
474+
#[inline(always)]
475+
pub fn alloc_slice<T>(&self, slice: &[T]) -> &mut [T]
476+
where
477+
T: Copy,
478+
{
479+
// Extend the lifetime of the result since it's limited to the lock guard
480+
unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
481+
}
482+
}
483+
413484
#[cfg(test)]
414485
mod tests {
415486
extern crate test;

0 commit comments

Comments
 (0)