Skip to content

Commit 67a3e28

Browse files
authored
Merge pull request #1 from maschad/mc/chore/fix-tests
2 parents 520ca82 + cb30057 commit 67a3e28

File tree

4 files changed

+568
-58
lines changed

4 files changed

+568
-58
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
[package]
2-
name = "spray"
3-
version = "0.1.0"
4-
edition = "2021"
2+
authors = ["Chad Nehemiah <chad.nehemiah94@gmail.com>"]
3+
categories = ["data-structures", "concurrency"]
4+
description = "A scalable concurrent priority queue with relaxed ordering semantics"
5+
edition = "2021"
6+
keywords = ["priority-queue", "concurrent", "lock-free", "data-structures", "skip-list"]
7+
license = "MIT"
8+
name = "spray"
9+
repository = "https://github.com/maschad/spray"
10+
version = "1.0.0"
511

612
[dev-dependencies]
713
criterion = "0.6.0"
814

915
[[bench]]
10-
name = "spraylist_bench"
1116
harness = false
17+
name = "spraylist_bench"
1218

1319
[[bin]]
1420
name = "throughput_test"

src/skiplist.rs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,10 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
140140
let mut succs = vec![ptr::null_mut(); MAX_LEVEL];
141141

142142
'retry: loop {
143-
let mut pred = self.head.load(AtomicOrdering::SeqCst);
143+
let mut pred = self.head.load(AtomicOrdering::Acquire);
144144

145145
for level in (0..MAX_LEVEL).rev() {
146-
let mut curr = unsafe { &*pred }.next[level].load(AtomicOrdering::SeqCst);
146+
let mut curr = unsafe { &*pred }.next[level].load(AtomicOrdering::Acquire);
147147

148148
loop {
149149
if curr.is_null() {
@@ -157,7 +157,7 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
157157
}
158158

159159
let curr_node = unsafe { &*curr_clean };
160-
let next = curr_node.next[level].load(AtomicOrdering::SeqCst);
160+
let next = curr_node.next[level].load(AtomicOrdering::Acquire);
161161

162162
// Skip marked nodes
163163
if is_marked(next) {
@@ -166,8 +166,8 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
166166
.compare_exchange(
167167
curr,
168168
next_clean,
169-
AtomicOrdering::SeqCst,
170-
AtomicOrdering::SeqCst,
169+
AtomicOrdering::AcqRel,
170+
AtomicOrdering::Acquire,
171171
)
172172
.is_err()
173173
{
@@ -212,22 +212,22 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
212212

213213
// Set next pointers
214214
for (i, succ) in succs.iter().enumerate().take(level + 1) {
215-
new_node_ref.next[i].store(*succ, AtomicOrdering::SeqCst);
215+
new_node_ref.next[i].store(*succ, AtomicOrdering::Release);
216216
}
217217

218218
// Try to link at level 0 first
219219
match unsafe { &*preds[0] }.next[0].compare_exchange(
220220
succs[0],
221221
new_node,
222-
AtomicOrdering::SeqCst,
223-
AtomicOrdering::SeqCst,
222+
AtomicOrdering::AcqRel,
223+
AtomicOrdering::Acquire,
224224
) {
225225
Ok(_) => {
226226
// Successfully linked at level 0, now link at higher levels
227227
for i in 1..=level {
228228
loop {
229229
let pred = &unsafe { &*preds[i] }.next[i];
230-
let curr_next = new_node_ref.next[i].load(AtomicOrdering::SeqCst);
230+
let curr_next = new_node_ref.next[i].load(AtomicOrdering::Acquire);
231231

232232
// If our node got marked, give up on higher levels
233233
if is_marked(curr_next) {
@@ -238,8 +238,8 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
238238
.compare_exchange(
239239
succs[i],
240240
new_node,
241-
AtomicOrdering::SeqCst,
242-
AtomicOrdering::SeqCst,
241+
AtomicOrdering::AcqRel,
242+
AtomicOrdering::Acquire,
243243
)
244244
.is_ok()
245245
{
@@ -250,7 +250,7 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
250250
let (new_preds, new_succs) = self.find(&new_node_ref.key);
251251
if i < new_preds.len() && i < new_succs.len() {
252252
// Update for this specific level and retry
253-
new_node_ref.next[i].store(new_succs[i], AtomicOrdering::SeqCst);
253+
new_node_ref.next[i].store(new_succs[i], AtomicOrdering::Release);
254254
if new_preds[i] != preds[i] {
255255
break; // Topology changed, stop trying higher levels
256256
}
@@ -289,14 +289,14 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
289289

290290
// Try to unlink at all levels
291291
for level in (0..=node.level).rev() {
292-
let next = node.next[level].load(AtomicOrdering::SeqCst);
292+
let next = node.next[level].load(AtomicOrdering::Acquire);
293293
let next_clean = unmark(next);
294294

295295
let _ = unsafe { &*preds[level] }.next[level].compare_exchange(
296296
succs[level],
297297
next_clean,
298-
AtomicOrdering::SeqCst,
299-
AtomicOrdering::SeqCst,
298+
AtomicOrdering::AcqRel,
299+
AtomicOrdering::Acquire,
300300
);
301301
}
302302

@@ -310,7 +310,7 @@ impl<K: Ord + Default + Clone, V: Default + Clone> SkipList<K, V> {
310310

311311
/// Get a reference to the head node (for `SprayList` operations)
312312
pub fn head(&self) -> *mut Node<K, V> {
313-
self.head.load(AtomicOrdering::SeqCst)
313+
self.head.load(AtomicOrdering::Acquire)
314314
}
315315

316316
/// Decrement the size counter (for `SprayList` operations)

0 commit comments

Comments
 (0)