-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented various backoffs and per-CPU rng
1. Modified crates/spinlock to provide support for multiple backoff strategies when encountering lock contention, including exp-backoff and rand-exp-backoff. 2. Modified `BaseSpinLock` in crates/spinlock to support locking with a different guard/backoff type, providing more flexibility. 3. Added a new module `ruxrand` that aims to provide support for the usage of RNGs inside kernel. Currently a per-CPU RNG and support for rand-exp-backoff in spinlock are implemented. 4. Changed the lock type used by `RunQueue`.
- Loading branch information
1 parent
24fa3dd
commit 21cc7ac
Showing
16 changed files
with
614 additions
and
29 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use core::ops::RangeInclusive; | ||
|
||
use crate::{Backoff, Relax}; | ||
|
||
/// Defines the interface to generate a random number within given range, | ||
/// which is to be used in random exponential backoff algorithm. | ||
#[crate_interface::def_interface] | ||
pub trait SpinRandIf { | ||
/// Generates a random number within given range. | ||
/// | ||
/// Note that this method may be called simultaneously on multiple CPUs, | ||
/// so the implementation should be thread-safe. | ||
fn percpu_rand(r: RangeInclusive<u32>) -> u32; | ||
} | ||
|
||
#[inline(always)] | ||
fn exp_rand_backoff(current_limit: &mut u32, max: u32) { | ||
use crate_interface::call_interface; | ||
|
||
let limit = *current_limit; | ||
*current_limit = max.max(limit); | ||
let delay = call_interface!(SpinRandIf::percpu_rand, 0..=limit); | ||
for _ in 0..delay { | ||
core::hint::spin_loop(); | ||
} | ||
} | ||
|
||
/// Call [`core::hint::spin_loop`] random times within an exponentially grown limit | ||
/// when backoff/relax is required. The random number is generated using [`SpinRandIf::percpu_rand`], | ||
/// which ought to be implemented by the user. | ||
/// | ||
/// This would generally increase performance when the lock is highly contended. | ||
#[derive(Debug)] | ||
pub struct ExpRand<const MAX: u32>(u32); | ||
|
||
impl<const N: u32> Relax for ExpRand<N> { | ||
#[inline(always)] | ||
fn relax(&mut self) { | ||
exp_rand_backoff(&mut self.0, N); | ||
} | ||
} | ||
|
||
impl<const N: u32> Backoff for ExpRand<N> { | ||
#[inline(always)] | ||
fn backoff(&mut self) { | ||
exp_rand_backoff(&mut self.0, N); | ||
} | ||
} | ||
|
||
impl<const N: u32> Default for ExpRand<N> { | ||
#[inline(always)] | ||
fn default() -> Self { | ||
Self(1) | ||
} | ||
} |
Oops, something went wrong.