macro_rules! global_lock {
{
$(#[$meta:meta])* $pub:vis
unsafe(uninit) static $name:ident: $kind:ident<$valuety:ty> = $value:expr;
} => { ... };
}
Expand description
Defines a global lock.
The global mutex must be initialized before first use. Usually this is done by calling
GlobalLock::init
in the module initializer.
§Examples
A global counter:
kernel::sync::global_lock! {
// SAFETY: Initialized in module initializer before first use.
unsafe(uninit) static MY_COUNTER: Mutex<u32> = 0;
}
fn increment_counter() -> u32 {
let mut guard = MY_COUNTER.lock();
*guard += 1;
*guard
}
impl kernel::Module for MyModule {
fn init(_module: &'static ThisModule) -> Result<Self> {
// SAFETY: Called exactly once.
unsafe { MY_COUNTER.init() };
Ok(MyModule {})
}
}
A global mutex used to protect all instances of a given struct:
use kernel::sync::{GlobalGuard, GlobalLockedBy};
kernel::sync::global_lock! {
// SAFETY: Initialized in module initializer before first use.
unsafe(uninit) static MY_MUTEX: Mutex<()> = ();
}
/// All instances of this struct are protected by `MY_MUTEX`.
struct MyStruct {
my_counter: GlobalLockedBy<u32, MY_MUTEX>,
}
impl MyStruct {
/// Increment the counter in this instance.
///
/// The caller must hold the `MY_MUTEX` mutex.
fn increment(&self, guard: &mut GlobalGuard<MY_MUTEX>) -> u32 {
let my_counter = self.my_counter.as_mut(guard);
*my_counter += 1;
*my_counter
}
}
impl kernel::Module for MyModule {
fn init(_module: &'static ThisModule) -> Result<Self> {
// SAFETY: Called exactly once.
unsafe { MY_MUTEX.init() };
Ok(MyModule {})
}
}