Skip to content

Commit 61666a2

Browse files
committed
hard manual written finish
1 parent cf4b8ea commit 61666a2

File tree

1 file changed

+90
-25
lines changed

1 file changed

+90
-25
lines changed

homework/src/list_set/optimistic_fine_grained.rs

Lines changed: 90 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::cmp::Ordering::*;
2-
use std::mem::{self, ManuallyDrop};
2+
use std::fmt::write;
3+
use std::mem::{self, ManuallyDrop, replace, take};
34
use std::sync::atomic::Ordering::*;
45

56
use crossbeam_epoch::{Atomic, Guard, Owned, Shared, pin};
@@ -49,7 +50,8 @@ impl<'g, T: Ord> Cursor<'g, T> {
4950
if curr_node.data == *key {
5051
return Ok(true);
5152
}
52-
self.prev = unsafe { curr_node.next.read_lock() };
53+
let prev = replace(&mut self.prev, unsafe { curr_node.next.read_lock() });
54+
prev.finish();
5355
self.curr = self.prev.load(SeqCst, guard);
5456
} else {
5557
return Ok(false);
@@ -77,17 +79,23 @@ impl<T> OptimisticFineGrainedListSet<T> {
7779
impl<T: Ord> OptimisticFineGrainedListSet<T> {
7880
fn find<'g>(&'g self, key: &T, guard: &'g Guard) -> Result<(bool, Cursor<'g, T>), ()> {
7981
let mut cur = self.head(guard);
80-
cur.find(key, guard).map(|found| {
81-
(true, cur)
82-
})
82+
if let Ok(found) = cur.find(key, guard) {
83+
Ok((found, cur))
84+
} else {
85+
cur.prev.finish();
86+
Err(())
87+
}
8388
}
8489
}
8590

8691
impl<T: Ord> ConcurrentSet<T> for OptimisticFineGrainedListSet<T> {
8792
fn contains(&self, key: &T) -> bool {
8893
let guard = pin();
8994
match self.find(key, &guard) {
90-
Ok((found, _)) => found,
95+
Ok((found, cursor)) => {
96+
cursor.prev.finish();
97+
found
98+
}
9199
Err(_) => false,
92100
}
93101
}
@@ -103,10 +111,14 @@ impl<T: Ord> ConcurrentSet<T> for OptimisticFineGrainedListSet<T> {
103111
if let Some(curr_node) = unsafe { cur.curr.as_ref() } {
104112
match curr_node.data.cmp(&key) {
105113
Less => {
114+
cur.prev.finish();
106115
cur.prev = unsafe { curr_node.next.read_lock() };
107116
cur.curr = cur.prev.load(SeqCst, &guard);
108-
},
109-
Equal => return false,
117+
}
118+
Equal => {
119+
cur.prev.finish(); // FUCK finish
120+
return false;
121+
}
110122
Greater => break 'outer,
111123
}
112124
} else {
@@ -116,27 +128,52 @@ impl<T: Ord> ConcurrentSet<T> for OptimisticFineGrainedListSet<T> {
116128

117129
// Insert before the current node
118130
let new_node = Node::new(key, cur.curr);
119-
cur.prev.store(new_node, SeqCst);
120-
return true;
131+
if let Ok(write_guard) = cur.prev.upgrade() {
132+
write_guard.store(new_node, SeqCst);
133+
}
134+
true
121135
}
122136

123137
fn remove(&self, key: &T) -> bool {
138+
/*
139+
write lock the previous node
140+
*/
124141
let guard = pin();
125-
loop {
126-
if let Ok((found, mut cursor)) = self.find(key, &guard) {
127-
if !found {
128-
return false;
129-
}
130-
if let Some(curr_node) = unsafe { cursor.curr.as_ref() } {
131-
if cursor.prev.validate() {
132-
let next_guard = unsafe { curr_node.next.read_lock() };
133-
while let Err(()) = cursor.prev.clone().upgrade() {}
134-
// todo upgrade to write lock
135-
todo!();
142+
143+
// deal with the first node
144+
'outer: loop {
145+
let mut cursor = self.head(&guard);
146+
loop {
147+
if cursor.prev.validate() {
148+
if let Some(curr_node) = unsafe { cursor.curr.as_ref() } {
149+
match curr_node.data.cmp(key) {
150+
Less => {
151+
cursor.prev.finish();
152+
cursor.prev = unsafe { curr_node.next.read_lock() };
153+
cursor.curr = cursor.prev.load(SeqCst, &guard);
154+
}
155+
Equal => {
156+
if !cursor.prev.validate() {
157+
continue 'outer; // retry because the previous node is invalid. It's destroyed by write lock.
158+
}
159+
let write_guard = cursor.prev.upgrade().unwrap();
160+
let write_guiard_next = curr_node.next.write_lock(); // !!! to invalidate iterator.
161+
write_guard.store(write_guiard_next.load(SeqCst, &guard), SeqCst);
162+
unsafe {
163+
guard.defer_destroy(cursor.curr);
164+
}
165+
return true;
166+
}
167+
Greater => {
168+
cursor.prev.finish();
169+
return false;
170+
}
171+
}
172+
} else {
173+
cursor.prev.finish();
174+
return false;
136175
}
137176
}
138-
} else {
139-
// find failed, try again
140177
}
141178
}
142179
}
@@ -164,13 +201,41 @@ impl<'g, T> Iterator for Iter<'g, T> {
164201
type Item = Result<&'g T, ()>;
165202

166203
fn next(&mut self) -> Option<Self::Item> {
167-
todo!()
204+
if !self.cursor.prev.validate() {
205+
return Some(Err(()));
206+
}
207+
if let Some(curr_node) = unsafe { self.cursor.curr.as_ref() } {
208+
let cur = unsafe { ManuallyDrop::take(&mut self.cursor) };
209+
let next_prev_guard = unsafe { curr_node.next.read_lock() };
210+
if !next_prev_guard.validate() {
211+
return Some(Err(()));
212+
}
213+
let next_node = next_prev_guard.load(SeqCst, self.guard);
214+
self.cursor = ManuallyDrop::new(Cursor {
215+
prev: next_prev_guard,
216+
curr: next_node,
217+
});
218+
cur.prev.finish();
219+
Some(Ok(&curr_node.data))
220+
} else {
221+
None
222+
}
168223
}
169224
}
170225

171226
impl<T> Drop for OptimisticFineGrainedListSet<T> {
172227
fn drop(&mut self) {
173-
todo!()
228+
let guard = pin();
229+
let read_guard = unsafe { self.head.read_lock() };
230+
let mut cur_node = read_guard.load(SeqCst, &guard);
231+
read_guard.finish();
232+
while !cur_node.is_null() {
233+
let node = unsafe { cur_node.into_owned() };
234+
let read_guard = unsafe { node.next.read_lock() };
235+
cur_node = read_guard.load(SeqCst, &guard);
236+
read_guard.finish();
237+
drop(node);
238+
}
174239
}
175240
}
176241

0 commit comments

Comments
 (0)