Monitor::lock_with_handshake
This commit is contained in:
parent
66829edd74
commit
13d3fcdffe
1 changed files with 38 additions and 1 deletions
|
@ -58,7 +58,7 @@ pub struct Monitor<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Monitor<T> {
|
impl<T> Monitor<T> {
|
||||||
pub fn new(value: T) -> Self {
|
pub const fn new(value: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
mutex: Mutex::new(value),
|
mutex: Mutex::new(value),
|
||||||
cvar: Condvar::new(),
|
cvar: Condvar::new(),
|
||||||
|
@ -86,6 +86,43 @@ impl<T> Monitor<T> {
|
||||||
guard
|
guard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lock_with_handshake<VM: VirtualMachine>(&self) -> MonitorGuard<T> {
|
||||||
|
let my_slot = get_thread_id().get();
|
||||||
|
let guard = if my_slot != self.holder.load(Ordering::Relaxed) {
|
||||||
|
let guard = self.lock_with_handshake_no_rec::<VM>();
|
||||||
|
self.holder.store(my_slot, Ordering::Release);
|
||||||
|
guard
|
||||||
|
} else {
|
||||||
|
MonitorGuard {
|
||||||
|
monitor: self,
|
||||||
|
guard: unsafe { ManuallyDrop::new(self.mutex.make_guard_unchecked()) },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
self.rec_count.fetch_add(1, Ordering::Relaxed);
|
||||||
|
guard
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lock_with_handshake_no_rec<VM: VirtualMachine>(&self) -> MonitorGuard<'_, T> {
|
||||||
|
let tls = Thread::<VM>::current();
|
||||||
|
tls.context.save_thread_state();
|
||||||
|
|
||||||
|
let mutex_guard = loop {
|
||||||
|
Thread::<VM>::enter_native();
|
||||||
|
let guard = self.mutex.lock();
|
||||||
|
if Thread::<VM>::attempt_leave_native_no_block() {
|
||||||
|
break guard;
|
||||||
|
} else {
|
||||||
|
drop(guard);
|
||||||
|
Thread::<VM>::leave_native();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
MonitorGuard {
|
||||||
|
monitor: self,
|
||||||
|
guard: ManuallyDrop::new(mutex_guard),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn notify(&self) {
|
pub fn notify(&self) {
|
||||||
self.cvar.notify_one();
|
self.cvar.notify_one();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue