Is there a reason why you think PCell::get_ref
, PCell::update_inplace
, PCell::update_inplace_mut
and the various math functions on PCell
are sound? Because it doesn't look like they are.
use corundum::cell::PCell;
use corundum::prc::Prc;
use corundum::clone::PClone;
use corundum::alloc::{MemPool, heap::Heap};
fn main() {
Heap::transaction(|j| {
let foo = Prc::new(PCell::new(1), &j);
let foo2 = foo.pclone(&j);
foo.update_inplace_mut(&j, |foo| {
foo2.update_inplace_mut(&j, |foo2| {
// `foo` and `foo2` are mutable references to the same type,
// so it's unsound for them to point to the same object
assert_ne!(foo as *mut _, foo2 as *mut _); // oops, this fails
});
});
}).unwrap();
}
Also, did you test this with miri? I tried running this snippet with miri, but it doesn't even get to the update_inplace_mut
call, it fails when detecting an unaligned read in Heap::transation
error: Undefined Behavior: accessing memory with alignment 1, but alignment 8 is required
--> G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\utils.rs:80:5
|
80 | &mut *U { raw }.rf
| ^^^^^^^^^^^^^^^^^^ accessing memory with alignment 1, but alignment 8 is required
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
= note: inside `corundum::utils::read::<corundum::stm::Journal<corundum::alloc::heap::Heap>>` at G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\utils.rs:80:5
= note: inside `<corundum::alloc::heap::Heap as corundum::alloc::MemPool>::atomic_new::<corundum::stm::Journal<corundum::alloc::heap::Heap>>` at G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\alloc\pool.rs:816:17
= note: inside closure at G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\stm\journal.rs:603:51
= note: inside `<corundum::alloc::heap::Heap as corundum::alloc::MemPool>::journals::<std::option::Option<(*const corundum::stm::Journal<corundum::alloc::heap::Heap>, *mut i32)>, [closure@corundum::stm::Journal<corundum::alloc::heap::Heap>::current::{closure#0}]>` at G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\alloc\heap.rs:162:9
= note: inside `corundum::stm::Journal::<corundum::alloc::heap::Heap>::current` at G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\stm\journal.rs:598:13
= note: inside closure at G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\alloc\pool.rs:1137:29
= note: inside `std::panicking::r#try::do_call::<[closure@<corundum::alloc::heap::Heap as corundum::alloc::MemPool>::transaction<(), [closure@src\main.rs:7:20: 21:3]>::{closure#0}], ()>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:379:40
= note: inside `std::panicking::r#try::<(), [closure@<corundum::alloc::heap::Heap as corundum::alloc::MemPool>::transaction<(), [closure@src\main.rs:7:20: 21:3]>::{closure#0}]>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:343:19
= note: inside `std::panic::catch_unwind::<[closure@<corundum::alloc::heap::Heap as corundum::alloc::MemPool>::transaction<(), [closure@src\main.rs:7:20: 21:3]>::{closure#0}], ()>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:431:14
= note: inside `<corundum::alloc::heap::Heap as corundum::alloc::MemPool>::transaction::<(), [closure@src\main.rs:7:20: 21:3]>` at G:\Programmi\Rust\.cargo\registry\src\github.com-1ecc6299db9ec823\corundum-0.3.3\src\alloc\pool.rs:1108:19note: inside `main` at src\main.rs:7:2
--> src\main.rs:7:2
|
7 | / Heap::transaction(|j| {
8 | | let foo = Prc::new(PCell::new(1), &j);
9 | | let foo2 = foo.pclone(&j);
10 | |
... |
20 | | });
21 | | }).unwrap();
| |______^
= note: inside `<fn() as std::ops::FnOnce<()>>::call_once - shim(fn())` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:227:5
= note: inside `std::sys_common::backtrace::__rust_begin_short_backtrace::<fn(), ()>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sys_common\backtrace.rs:125:18
= note: inside closure at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:66:18
= note: inside `std::ops::function::impls::<impl std::ops::FnOnce<()> for &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>::call_once` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:259:13
= note: inside `std::panicking::r#try::do_call::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:379:40
= note: inside `std::panicking::r#try::<i32, &dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:343:19
= note: inside `std::panic::catch_unwind::<&dyn std::ops::Fn() -> i32 + std::marker::Sync + std::panic::RefUnwindSafe, i32>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:431:14
= note: inside `std::rt::lang_start_internal` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:51:25
= note: inside `std::rt::lang_start::<()>` at G:\Programmi\Rust\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:65:5
error: aborting due to previous error
Edit: a more simple example that allows to access arbitrary data
use corundum::cell::PCell;
use corundum::boxed::Pbox;
use corundum::alloc::{MemPool, heap::Heap};
fn main() {
Heap::transaction(|j| {
let foo = PCell::new(Ok(Pbox::new(42, &j)));
let r = foo.get_ref().as_ref().unwrap();
foo.set(Err((isize::MAX as usize, 0u8)), &j);
println!("{}", *r);
}).unwrap();
}
When run:
PS G:\WorkSpace\rust-playground> cargo +nightly run
Compiling rust-playground v0.1.0 (G:\WorkSpace\rust-playground)
Finished dev [unoptimized + debuginfo] target(s) in 0.37s
Running `target\debug\rust-playground.exe`
error: process didn't exit successfully: `target\debug\rust-playground.exe` (exit code: 0xc0000005, STATUS_ACCESS_VIOLATION)