Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update seize to 0.3 #123

Merged
merged 5 commits into from
Apr 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/safety.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ jobs:
- name: cargo miri test
run: cargo miri test
env:
MIRIFLAGS: "-Zmiri-tag-raw-pointers -Zmiri-disable-isolation"
MIRIFLAGS: "-Zmiri-disable-isolation"
8 changes: 2 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ parking_lot = "0.12"
num_cpus = "1.12.0"
rayon = {version = "1.3", optional = true}
serde = {version = "1.0.105", optional = true}
seize = "0.2.1"
seize = "0.3.3"

[dependencies.ahash]
version = "0.8.4"
Expand Down
2 changes: 1 addition & 1 deletion src/iter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ mod tests {
let mut guard = map.guard();
map.insert(1, 42, &guard);
map.insert(2, 84, &guard);
guard.flush();
guard.refresh();

assert_eq!(
map.values(&guard).collect::<HashSet<&usize>>(),
Expand Down
53 changes: 18 additions & 35 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1020,15 +1020,11 @@ where
// the new bin will also be a tree bin. if both the high
// bin and the low bin are non-empty, we have to
// allocate a new TreeBin.
Shared::boxed(
BinEntry::Tree(TreeBin::new(
// safety: we have just created `low` and its `next`
// nodes and have never shared them
unsafe { low.into_box() },
guard,
)),
&self.collector,
)
// safety: we have just created `low` and its `next` nodes using `Shared::boxed`
// and have never shared them
let low_bin = unsafe { BinEntry::Tree(TreeBin::new(low, guard)) };

Shared::boxed(low_bin, &self.collector)
} else {
// if not, we can re-use the old bin here, since it will
// be swapped for a Moved entry while we are still
Expand All @@ -1048,15 +1044,11 @@ where
unsafe { TreeBin::drop_tree_nodes(high, false, guard) };
high_linear
} else if low_count != 0 {
Shared::boxed(
BinEntry::Tree(TreeBin::new(
// safety: we have just created `high` and its `next`
// nodes and have never shared them
unsafe { high.into_box() },
guard,
)),
&self.collector,
)
// safety: we have just created `high` and its `next` nodes using `Shared::boxed`
// and have never shared them
let high_bin = unsafe { BinEntry::Tree(TreeBin::new(high, guard)) };

Shared::boxed(high_bin, &self.collector)
} else {
reused_bin = true;
// since we also don't use the created low nodes here,
Expand Down Expand Up @@ -1664,7 +1656,7 @@ where
not_inserted,
} => Err(TryInsertError {
current,
not_inserted: Linked::into_inner(*not_inserted),
not_inserted: not_inserted.value,
}),
PutResult::Inserted { new } => Ok(new),
PutResult::Replaced { .. } => {
Expand Down Expand Up @@ -1731,9 +1723,7 @@ where
Err(changed) => {
assert!(!changed.current.is_null());
bin = changed.current;
if let BinEntry::Node(node) =
Linked::into_inner(*unsafe { changed.new.into_box() })
{
if let BinEntry::Node(node) = unsafe { changed.new.into_box() }.value {
key = node.key;
} else {
unreachable!("we declared node and it is a BinEntry::Node");
Expand Down Expand Up @@ -2795,18 +2785,11 @@ where
tail = new_tree_node;
e = e_deref.next.load(Ordering::SeqCst, guard);
}
tab.store_bin(
index,
Shared::boxed(
BinEntry::Tree(TreeBin::new(
// safety: we have just created `head` and its `next`
// nodes and have never shared them
unsafe { head.into_box() },
guard,
)),
&self.collector,
),
);

// safety: we have just created `head` and its `next` nodes using `Shared::boxed`
// and have never shared them
let head_bin = unsafe { BinEntry::Tree(TreeBin::new(head, guard)) };
tab.store_bin(index, Shared::boxed(head_bin, &self.collector));
drop(lock);
// make sure the old bin entries get dropped
e = bin;
Expand Down Expand Up @@ -3317,7 +3300,7 @@ fn no_replacement_return_val() {
map.put(42, String::from("world"), true, &guard),
PutResult::Exists {
current: &String::from("hello"),
not_inserted: Box::new(map.collector.link(String::from("world"))),
not_inserted: Box::new(map.collector.link_value(String::from("world"))),
}
);
}
Expand Down
29 changes: 16 additions & 13 deletions src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::raw::Table;
use crate::reclaim::{Atomic, Collector, Guard, RetireShared, Shared};
use core::sync::atomic::{AtomicBool, AtomicI64, Ordering};
use parking_lot::Mutex;
use seize::Linked;
use seize::{Link, Linked};
use std::borrow::Borrow;
use std::thread::{current, park, Thread};

Expand Down Expand Up @@ -241,9 +241,12 @@ where
/// Constructs a new bin from the given nodes.
///
/// Nodes are arranged into an ordered red-black tree.
pub(crate) fn new(bin: Box<Linked<BinEntry<K, V>>>, guard: &Guard<'_>) -> Self {
///
/// # Safety
///
/// The `bin` pointer and its successors were created with `Shared::boxed` and never shared.
pub(crate) unsafe fn new(bin: Shared<'_, BinEntry<K, V>>, guard: &Guard<'_>) -> Self {
let mut root = Shared::null();
let bin = Shared::from(Box::into_raw(bin));

// safety: We own the nodes for creating this new TreeBin, so they are
// not shared with another thread and cannot get invalidated.
Expand Down Expand Up @@ -937,16 +940,16 @@ impl<K, V> TreeBin<K, V> {
bin: Shared<'g, BinEntry<K, V>>,
guard: &'g Guard<'_>,
) {
guard.retire(bin.as_ptr(), |mut link| {
guard.defer_retire(bin.as_ptr(), |link| {
let bin = unsafe {
// SAFETY: `bin` is a `BinEntry<K, V>`
let ptr = link.cast::<BinEntry<K, V>>();
// SAFETY: `bin` is a `Linked<BinEntry<K, V>>`
let ptr: *mut Linked<BinEntry<K, V>> = Link::cast(link);
// SAFETY: `retire` guarantees that we
// have unique access to `bin` at this point
*Box::from_raw(ptr)
Box::from_raw(ptr).value
};

if let BinEntry::Tree(mut tree_bin) = Linked::into_inner(bin) {
if let BinEntry::Tree(mut tree_bin) = bin {
tree_bin.drop_fields(false);
} else {
unreachable!("bin is a tree bin");
Expand Down Expand Up @@ -985,7 +988,7 @@ impl<K, V> TreeBin<K, V> {
) {
let mut p = from;
while !p.is_null() {
if let BinEntry::TreeNode(tree_node) = Linked::into_inner(*p.into_box()) {
if let BinEntry::TreeNode(tree_node) = p.into_box().value {
// if specified, drop the value in this node
if drop_values {
let _ = tree_node.node.value.into_box();
Expand Down Expand Up @@ -1544,7 +1547,7 @@ mod tests {
let entry = table.get_moved(table2, &guard);
table.store_bin(0, entry);
assert!(table
.find(&collector.link(BinEntry::Moved), 1, &2, &guard)
.find(&collector.link_value(BinEntry::Moved), 1, &2, &guard)
.is_null());
table.drop_bins();
// safety: table2 is still valid and not accessed by different threads
Expand All @@ -1562,7 +1565,7 @@ mod tests {
let entry = table.get_moved(table2, &guard);
table.store_bin(0, entry);
assert!(table
.find(&collector.link(BinEntry::Moved), 1, &2, &guard)
.find(&collector.link_value(BinEntry::Moved), 1, &2, &guard)
.is_null());
table.drop_bins();
// safety: table2 is still valid and not accessed by different threads
Expand All @@ -1584,7 +1587,7 @@ mod tests {
let entry = table.get_moved(table2, &guard);
table.store_bin(0, entry);
assert!(table
.find(&collector.link(BinEntry::Moved), 0, &1, &guard)
.find(&collector.link_value(BinEntry::Moved), 0, &1, &guard)
.is_null());
table.drop_bins();
// safety: table2 is still valid and not accessed by different threads
Expand All @@ -1611,7 +1614,7 @@ mod tests {
// entry was not removed
unsafe {
table
.find(&collector.link(BinEntry::Moved), 1, &2, &guard)
.find(&collector.link_value(BinEntry::Moved), 1, &2, &guard)
.deref()
}
.as_node()
Expand Down
4 changes: 2 additions & 2 deletions src/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ impl<K, V> Table<K, V> {
// we replaced the bin with a NULL, so there's no future way to access it
// either; we own all the nodes in the list.

let node = if let BinEntry::Node(node) = Linked::into_inner(*p) {
let node = if let BinEntry::Node(node) = p.value {
node
} else {
unreachable!();
Expand All @@ -228,7 +228,7 @@ impl<K, V> Table<K, V> {
BinEntry::Tree(_) => {
// safety: same as for BinEntry::Node
let p = unsafe { bin.into_box() };
let bin = if let BinEntry::Tree(bin) = Linked::into_inner(*p) {
let bin = if let BinEntry::Tree(bin) = p.value {
bin
} else {
unreachable!();
Expand Down
8 changes: 4 additions & 4 deletions src/reclaim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ pub(crate) use seize::{Collector, Guard, Linked};

use std::marker::PhantomData;
use std::ops::Deref;
use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicPtr, Ordering};
use std::{fmt, ptr};

pub(crate) struct Atomic<T>(seize::AtomicPtr<T>);
pub(crate) struct Atomic<T>(AtomicPtr<Linked<T>>);

impl<T> Atomic<T> {
pub(crate) fn null() -> Self {
Self(seize::AtomicPtr::default())
Self(AtomicPtr::default())
}

pub(crate) fn load<'g>(&self, ordering: Ordering, guard: &'g Guard<'_>) -> Shared<'g, T> {
Expand Down Expand Up @@ -149,7 +149,7 @@ pub(crate) trait RetireShared {

impl RetireShared for Guard<'_> {
unsafe fn retire_shared<T>(&self, shared: Shared<'_, T>) {
self.retire(shared.ptr, seize::reclaim::boxed::<T>);
self.defer_retire(shared.ptr, seize::reclaim::boxed::<Linked<T>>);
}
}

Expand Down
Loading