pub(crate) struct WorkerMonitor {
worker_count: usize,
sync: Mutex<WorkerMonitorSync>,
active_workers: AtomicUsize,
workers_have_anything_to_do: Condvar,
active_worker_number_changed: Condvar,
}Expand description
A data structure for synchronizing workers with each other and with mutators.
Unlike GCWorkerShared, there is only one instance of WorkerMonitor.
- It allows workers to park and unpark.
- It allows mutators to notify workers to schedule a GC.
Fields§
§worker_count: usizeThe total number of workers.
sync: Mutex<WorkerMonitorSync>The synchronized part.
active_workers: AtomicUsizeThe number of workers that are allowed to execute work after being notified.
workers_have_anything_to_do: CondvarActive workers wait on this when idle. A parked active worker is notified if workers have things to do. That includes:
- any work packets available, and
- any field in
sync.goals.requestsset to true.
active_worker_number_changed: CondvarInactive workers wait on this instead. They are notified whenever the number of active workers changes, which may turn them into active workers.
Implementations§
Source§impl WorkerMonitor
impl WorkerMonitor
pub fn new(worker_count: usize) -> Self
pub(crate) fn active_workers(&self) -> usize
pub(crate) fn is_worker_active(&self, ordinal: usize) -> bool
Sourcepub fn set_active_workers(&self, active_workers: usize)
pub fn set_active_workers(&self, active_workers: usize)
Set the number of workers that are allowed to execute work after being notified.
This only updates the count. Whenever this changes, the caller must also call
notify_work_available(true) (directly, or indirectly via the on_last_parked
call-back while still holding the monitor’s internal lock) so that both active and
inactive workers wake up and re-evaluate whether they should be active. We don’t do the
notification here because this function may be called while the current thread is the
last parked worker executing on_last_parked, in which case the notification has to
happen through the already-held lock instead of acquiring it again.
Sourcepub fn make_request(&self, goal: WorkerGoal)
pub fn make_request(&self, goal: WorkerGoal)
Make a request. Can be called by a mutator to request the workers to work towards the
given goal.
Sourcepub fn notify_work_available(&self, all: bool)
pub fn notify_work_available(&self, all: bool)
Wake up workers when more work packets are made available for workers, or a mutator has requested the GC workers to schedule a GC.
Sourcefn notify_work_available_while_locked(&self, all: bool)
fn notify_work_available_while_locked(&self, all: bool)
Like notify_work_available, but for use by callers that already hold the monitor’s
internal lock (such as park_and_wait below), to avoid trying to lock it again.
Sourcepub fn park_and_wait<F>(
&self,
ordinal: usize,
on_last_parked: F,
) -> Result<(), WorkerShouldExit>
pub fn park_and_wait<F>( &self, ordinal: usize, on_last_parked: F, ) -> Result<(), WorkerShouldExit>
Park a worker and wait on the CondVar workers_have_anything_to_do.
If it is the last worker parked, on_last_parked will be called.
The argument of on_last_parked is true if sync.gc_requested is true.
The return value of on_last_parked will determine whether this worker and other workers
will wake up or block waiting.
This function returns Ok(()) if the current worker should continue working,
or Err(WorkerShouldExit) if the current worker should exit now.
Sourcepub fn on_all_workers_exited(&self)
pub fn on_all_workers_exited(&self)
Called when all workers have exited.
Auto Trait Implementations§
impl !Freeze for WorkerMonitor
impl RefUnwindSafe for WorkerMonitor
impl Send for WorkerMonitor
impl Sync for WorkerMonitor
impl Unpin for WorkerMonitor
impl UnwindSafe for WorkerMonitor
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSend for T
impl<T> DowncastSend for T
§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more