summaryrefslogtreecommitdiffstats
path: root/rust
diff options
context:
space:
mode:
Diffstat (limited to 'rust')
-rw-r--r--rust/kernel/sync/condvar.rs38
-rw-r--r--rust/kernel/task.rs15
2 files changed, 34 insertions, 19 deletions
diff --git a/rust/kernel/sync/condvar.rs b/rust/kernel/sync/condvar.rs
index 3f148d7040bb..9f1d83589beb 100644
--- a/rust/kernel/sync/condvar.rs
+++ b/rust/kernel/sync/condvar.rs
@@ -7,11 +7,17 @@
use super::{lock::Backend, lock::Guard, LockClassKey};
use crate::{
- bindings, init::PinInit, pin_init, str::CStr, task::MAX_SCHEDULE_TIMEOUT, time::Jiffies,
+ bindings,
+ init::PinInit,
+ pin_init,
+ str::CStr,
+ task::{MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE, TASK_NORMAL, TASK_UNINTERRUPTIBLE},
+ time::Jiffies,
types::Opaque,
};
-use core::ffi::c_long;
+use core::ffi::{c_int, c_long};
use core::marker::PhantomPinned;
+use core::ptr;
use macros::pin_data;
/// Creates a [`CondVar`] initialiser with the given name and a newly-created lock class.
@@ -108,7 +114,7 @@ impl CondVar {
fn wait_internal<T: ?Sized, B: Backend>(
&self,
- wait_state: u32,
+ wait_state: c_int,
guard: &mut Guard<'_, T, B>,
timeout_in_jiffies: c_long,
) -> c_long {
@@ -119,11 +125,7 @@ impl CondVar {
// SAFETY: Both `wait` and `wait_queue_head` point to valid memory.
unsafe {
- bindings::prepare_to_wait_exclusive(
- self.wait_queue_head.get(),
- wait.get(),
- wait_state as _,
- )
+ bindings::prepare_to_wait_exclusive(self.wait_queue_head.get(), wait.get(), wait_state)
};
// SAFETY: Switches to another thread. The timeout can be any number.
@@ -142,7 +144,7 @@ impl CondVar {
/// [`CondVar::notify_one`] or [`CondVar::notify_all`]. Note that it may also wake up
/// spuriously.
pub fn wait<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) {
- self.wait_internal(bindings::TASK_UNINTERRUPTIBLE, guard, MAX_SCHEDULE_TIMEOUT);
+ self.wait_internal(TASK_UNINTERRUPTIBLE, guard, MAX_SCHEDULE_TIMEOUT);
}
/// Releases the lock and waits for a notification in interruptible mode.
@@ -153,7 +155,7 @@ impl CondVar {
/// Returns whether there is a signal pending.
#[must_use = "wait_interruptible returns if a signal is pending, so the caller must check the return value"]
pub fn wait_interruptible<T: ?Sized, B: Backend>(&self, guard: &mut Guard<'_, T, B>) -> bool {
- self.wait_internal(bindings::TASK_INTERRUPTIBLE, guard, MAX_SCHEDULE_TIMEOUT);
+ self.wait_internal(TASK_INTERRUPTIBLE, guard, MAX_SCHEDULE_TIMEOUT);
crate::current!().signal_pending()
}
@@ -169,7 +171,7 @@ impl CondVar {
jiffies: Jiffies,
) -> CondVarTimeoutResult {
let jiffies = jiffies.try_into().unwrap_or(MAX_SCHEDULE_TIMEOUT);
- let res = self.wait_internal(bindings::TASK_INTERRUPTIBLE, guard, jiffies);
+ let res = self.wait_internal(TASK_INTERRUPTIBLE, guard, jiffies);
match (res as Jiffies, crate::current!().signal_pending()) {
(jiffies, true) => CondVarTimeoutResult::Signal { jiffies },
@@ -178,15 +180,15 @@ impl CondVar {
}
}
- /// Calls the kernel function to notify the appropriate number of threads with the given flags.
- fn notify(&self, count: i32, flags: u32) {
+ /// Calls the kernel function to notify the appropriate number of threads.
+ fn notify(&self, count: c_int) {
// SAFETY: `wait_queue_head` points to valid memory.
unsafe {
bindings::__wake_up(
self.wait_queue_head.get(),
- bindings::TASK_NORMAL,
+ TASK_NORMAL,
count,
- flags as _,
+ ptr::null_mut(),
)
};
}
@@ -198,7 +200,7 @@ impl CondVar {
/// CPU.
pub fn notify_sync(&self) {
// SAFETY: `wait_queue_head` points to valid memory.
- unsafe { bindings::__wake_up_sync(self.wait_queue_head.get(), bindings::TASK_NORMAL) };
+ unsafe { bindings::__wake_up_sync(self.wait_queue_head.get(), TASK_NORMAL) };
}
/// Wakes a single waiter up, if any.
@@ -206,7 +208,7 @@ impl CondVar {
/// This is not 'sticky' in the sense that if no thread is waiting, the notification is lost
/// completely (as opposed to automatically waking up the next waiter).
pub fn notify_one(&self) {
- self.notify(1, 0);
+ self.notify(1);
}
/// Wakes all waiters up, if any.
@@ -214,7 +216,7 @@ impl CondVar {
/// This is not 'sticky' in the sense that if no thread is waiting, the notification is lost
/// completely (as opposed to automatically waking up the next waiter).
pub fn notify_all(&self) {
- self.notify(0, 0);
+ self.notify(0);
}
}
diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs
index 49a8e10d68f5..a3a4007db682 100644
--- a/rust/kernel/task.rs
+++ b/rust/kernel/task.rs
@@ -5,11 +5,24 @@
//! C header: [`include/linux/sched.h`](srctree/include/linux/sched.h).
use crate::{bindings, types::Opaque};
-use core::{ffi::c_long, marker::PhantomData, ops::Deref, ptr};
+use core::{
+ ffi::{c_int, c_long, c_uint},
+ marker::PhantomData,
+ ops::Deref,
+ ptr,
+};
/// A sentinel value used for infinite timeouts.
pub const MAX_SCHEDULE_TIMEOUT: c_long = c_long::MAX;
+/// Bitmask for tasks that are sleeping in an interruptible state.
+pub const TASK_INTERRUPTIBLE: c_int = bindings::TASK_INTERRUPTIBLE as c_int;
+/// Bitmask for tasks that are sleeping in an uninterruptible state.
+pub const TASK_UNINTERRUPTIBLE: c_int = bindings::TASK_UNINTERRUPTIBLE as c_int;
+/// Convenience constant for waking up tasks regardless of whether they are in interruptible or
+/// uninterruptible sleep.
+pub const TASK_NORMAL: c_uint = bindings::TASK_NORMAL as c_uint;
+
/// Returns the currently running task.
#[macro_export]
macro_rules! current {