Skip to content

Commit

Permalink
Merge pull request #87 from vorner/future-proof-rc
Browse files Browse the repository at this point in the history
Future-proof the Rc::as_ptr too
  • Loading branch information
vorner authored Dec 25, 2022
2 parents 634dd80 + 7af4c73 commit 81a56de
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/ref_cnt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,29 @@ unsafe impl<T> RefCnt for Rc<T> {
Rc::into_raw(me) as *mut T
}
fn as_ptr(me: &Rc<T>) -> *mut T {
// Slightly convoluted way to do this, but this avoids stacked borrows violations. The same
// intention as
//
// me as &T as *const T as *mut T
//
// We first create a "shallow copy" of me - one that doesn't really own its ref count
// (that's OK, me _does_ own it, so it can't be destroyed in the meantime).
// Then we can use into_raw (which preserves not having the ref count).
//
// We need to "revert" the changes we did. In current std implementation, the combination
// of from_raw and forget is no-op. But formally, into_raw shall be paired with from_raw
// and that read shall be paired with forget to properly "close the brackets". In future
// versions of STD, these may become something else that's not really no-op (unlikely, but
// possible), so we future-proof it a bit.

// SAFETY: &T cast to *const T will always be aligned, initialised and valid for reads
let ptr = Rc::into_raw(unsafe { std::ptr::read(me) });
ptr as *mut T
let ptr = ptr as *mut T;

// SAFETY: We got the pointer from into_raw just above
mem::forget(unsafe { Rc::from_raw(ptr) });

ptr
}
unsafe fn from_ptr(ptr: *const T) -> Rc<T> {
Rc::from_raw(ptr)
Expand Down

2 comments on commit 81a56de

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Track benchmarks

Benchmark suite Current: 81a56de Previous: 634dd80 Ratio
uncontended/load 18 ns/iter (± 0) 18 ns/iter (± 1) 1
uncontended/load_full 32 ns/iter (± 0) 32 ns/iter (± 2) 1
uncontended/load_many 51 ns/iter (± 0) 47 ns/iter (± 3) 1.09
uncontended/store 158 ns/iter (± 0) 153 ns/iter (± 9) 1.03
uncontended/cache 0 ns/iter (± 0) 0 ns/iter (± 0) NaN
concurrent_loads/load 30 ns/iter (± 14) 25 ns/iter (± 8) 1.20
concurrent_loads/load_full 43 ns/iter (± 15) 37 ns/iter (± 14) 1.16
concurrent_loads/load_many 51 ns/iter (± 29) 81 ns/iter (± 25) 0.63
concurrent_loads/store 1464 ns/iter (± 448) 1564 ns/iter (± 663) 0.94
concurrent_loads/cache 0 ns/iter (± 0) 0 ns/iter (± 0) NaN
concurrent_store/load 51 ns/iter (± 2) 70 ns/iter (± 8) 0.73
concurrent_store/load_full 89 ns/iter (± 13) 104 ns/iter (± 17) 0.86
concurrent_store/load_many 134 ns/iter (± 1) 153 ns/iter (± 9) 0.88
concurrent_store/store 1515 ns/iter (± 33) 849 ns/iter (± 63) 1.78
concurrent_store/cache 1 ns/iter (± 0) 1 ns/iter (± 0) 1

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Track benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 81a56de Previous: 634dd80 Ratio
concurrent_store/store 1515 ns/iter (± 33) 849 ns/iter (± 63) 1.78

This comment was automatically generated by workflow using github-action-benchmark.

CC: @vorner

Please sign in to comment.