The initial completion abstraction only added `complete_all()` and `wait_for_completion()`. `complete_all()` marks the completion permanently done, which makes a single `Completion` unsuitable for signalling the same event repeatedly: once `complete_all()` has run, every subsequent `wait_for_completion()` returns immediately without waiting.
Add `complete()`, which wakes a single waiter and increments the internal counter by one. Paired one-to-one with `wait_for_completion()`, it allows the same completion to be reused across multiple cycles, e.g. to wait for consecutive DMA transfers to finish. Acked-by: Gary Guo <[email protected]> Signed-off-by: Maurice Hieronymus <[email protected]> --- rust/kernel/sync/completion.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/rust/kernel/sync/completion.rs b/rust/kernel/sync/completion.rs index 1771bfc0ade2..d8150b7b0acb 100644 --- a/rust/kernel/sync/completion.rs +++ b/rust/kernel/sync/completion.rs @@ -90,6 +90,17 @@ fn as_raw(&self) -> *mut bindings::completion { self.inner.get() } + /// Signal a single task waiting on this completion. + /// + /// This method wakes up a single task waiting on this completion. + /// If no task is currently waiting, the next + /// [`Completion::wait_for_completion`] returns immediately. + #[inline] + pub fn complete(&self) { + // SAFETY: `self.as_raw()` is a pointer to a valid `struct completion`. + unsafe { bindings::complete(self.as_raw()) }; + } + /// Signal all tasks waiting on this completion. /// /// This method wakes up all tasks waiting on this completion; after this operation the @@ -105,7 +116,7 @@ pub fn complete_all(&self) { /// This method waits for the completion of a task; it is not interruptible and there is no /// timeout. /// - /// See also [`Completion::complete_all`]. + /// See also [`Completion::complete`] and [`Completion::complete_all`]. #[inline] pub fn wait_for_completion(&self) { // SAFETY: `self.as_raw()` is a pointer to a valid `struct completion`. -- 2.54.0
