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

Add RwLock support #67

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bfca527
Add RwLock impl
jean-airoldie Mar 24, 2024
b2b35b1
Fix imports & guard drop impl
jean-airoldie Mar 24, 2024
d225aa4
Add some tests
jean-airoldie Mar 24, 2024
37252b1
Add test
jean-airoldie Mar 24, 2024
94784d3
Add test
jean-airoldie Mar 24, 2024
f2df4ae
Rename confusing fn
jean-airoldie Mar 24, 2024
08342a5
Add unsafe doc
jean-airoldie Mar 24, 2024
b8a2ec6
Add contention tests
jean-airoldie Mar 24, 2024
e5518c0
Add basic wakeup tests
jean-airoldie Mar 24, 2024
137327e
Add poll after completion tests
jean-airoldie Mar 24, 2024
0a63d06
Add improved filtering method
jean-airoldie Mar 25, 2024
787d4ae
Fix wakeup on future dropped before completion
jean-airoldie Mar 25, 2024
b91e50c
Improve test debugging by using collapse_debuginfo
jean-airoldie Mar 25, 2024
066b100
Cleanup tests
jean-airoldie Mar 25, 2024
f7f0288
Add future cancellation test
jean-airoldie Mar 25, 2024
8d5e6a4
Add test for ignored notifications
jean-airoldie Mar 25, 2024
a61f305
Add test for ignored future wakeups
jean-airoldie Mar 25, 2024
eacf497
Add lock stealing tests for fairness
jean-airoldie Mar 25, 2024
516baaa
Add test to make sure context is updated
jean-airoldie Mar 25, 2024
28bff8c
Add priority test for upgrade
jean-airoldie Mar 25, 2024
7502d41
Add synchronous test for upgrade
jean-airoldie Mar 25, 2024
8577f63
Fix clippy issues
jean-airoldie Mar 25, 2024
d6f4a82
Improve test doc
jean-airoldie Mar 25, 2024
e41f7d2
Improve doc
jean-airoldie Mar 25, 2024
8dc7d6f
Rework waiter notification method for clarity
jean-airoldie Mar 25, 2024
870bd3f
Fix nb_immediate_read_waiters
jean-airoldie Mar 25, 2024
a4ef173
Upgrade upgrade doc
jean-airoldie Mar 25, 2024
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
84 changes: 84 additions & 0 deletions src/intrusive_double_linked_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,25 @@ impl<T> LinkedList<T> {
}
}

/// Adds a node at the back of the linked list.
///
/// Safety: This function is only safe as long as `node` is guaranteed to
/// get removed from the list before it gets moved or dropped.
/// In addition to this `node` may not be added to another other list before
/// it is removed from the current one.
pub unsafe fn add_back(&mut self, node: &mut ListNode<T>) {
node.next = None;
node.prev = self.tail;
match self.tail {
Some(mut tail) => tail.as_mut().next = Some(node.into()),
None => {}
};
self.tail = Some(node.into());
if self.head.is_none() {
self.head = Some(node.into());
}
}

/// Returns a reference to the first node in the linked list
/// The function is only safe as long as valid pointers are stored inside
/// the linked list.
Expand Down Expand Up @@ -321,6 +340,71 @@ impl<T> LinkedList<T> {
}
}
}

/// Iterate the list in reverse order by calling a callback on each list node
/// and determining what to do based on the control flow.
pub fn reverse_apply_while<F>(&mut self, mut func: F)
where
F: FnMut(&mut ListNode<T>) -> ControlFlow,
{
let mut current = self.tail;

while let Some(mut node) = current {
// Safety: We are exclusively using nodes that are already contained
// in the list so they will contain valid data. The nodes can also
// not be added to the list again during iteration, since the list
// is mutably borrowed.
unsafe {
let flow = func(node.as_mut());
match flow {
ControlFlow::Continue => {
current = node.as_mut().prev;
}
ControlFlow::Stop => return,
ControlFlow::RemoveAndStop
| ControlFlow::RemoveAndContinue => {
let node = node.as_mut();
match node.prev {
Some(mut prev) => {
prev.as_mut().next = node.next;
}
None => {
self.head = node.next;
}
}
match node.next {
Some(mut next) => {
next.as_mut().prev = node.prev;
}
None => {
self.tail = node.prev;
}
}
if let ControlFlow::RemoveAndStop = flow {
return;
} else {
current = node.prev;
}
}
}
}
}
}
}

/// The outcome of a callback.
pub enum ControlFlow {
/// Continue the iteration.
Continue,

/// Stop the iteration.
Stop,

/// Remove the current entry and stop the iteration.
RemoveAndStop,

/// Remove the current entry and continue the iteration.
RemoveAndContinue,
}

#[cfg(all(test, feature = "alloc"))] // Tests make use of Vec at the moment
Expand Down
17 changes: 17 additions & 0 deletions src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,20 @@ pub use self::semaphore::{
Semaphore, SemaphoreAcquireFuture, SemaphoreReleaser, SharedSemaphore,
SharedSemaphoreAcquireFuture, SharedSemaphoreReleaser,
};

mod rwlock;

pub use self::rwlock::{
GenericRwLock, GenericRwLockReadFuture, GenericRwLockReadGuard,
GenericRwLockUpgradableReadFuture, GenericRwLockUpgradableReadGuard,
GenericRwLockWriteFuture, GenericRwLockWriteGuard, LocalRwLock,
LocalRwLockReadFuture, LocalRwLockReadGuard,
LocalRwLockUpgradableReadFuture, LocalRwLockUpgradableReadGuard,
LocalRwLockWriteFuture, LocalRwLockWriteGuard,
};

#[cfg(feature = "std")]
pub use self::rwlock::{
RwLock, RwLockReadFuture, RwLockReadGuard, RwLockUpgradableReadFuture,
RwLockUpgradableReadGuard, RwLockWriteFuture, RwLockWriteGuard,
};
Loading