Add idle context

This commit is contained in:
Wildan M
2026-04-23 05:41:03 +07:00
parent 7827cb6c78
commit 7adceb6e80
2 changed files with 40 additions and 2 deletions
+1
View File
@@ -132,6 +132,7 @@ pub fn init(token: &mut CleanLockToken) {
percpu
.switch_internals
.set_current_context(Arc::clone(&context_lock));
percpu.switch_internals.set_idle_context(context_lock);
}
run_contexts(token.downgrade()).set[priority].push_back(context_ref);
+39 -2
View File
@@ -177,6 +177,7 @@ pub fn switch(token: &mut CleanLockToken) -> SwitchResult {
let mut wakeups = Vec::new();
{
let current_context = context::current();
let idle_context = percpu.switch_internals.idle_context();
let mut contexts_guard = contexts(token.downgrade());
let (context, mut token) = contexts_guard.token_split();
@@ -184,6 +185,9 @@ pub fn switch(token: &mut CleanLockToken) -> SwitchResult {
if Arc::ptr_eq(&context_ref, &current_context) {
continue;
}
if Arc::ptr_eq(&context_ref, &idle_context) {
continue;
}
let guard = context_ref.read(token.token());
if guard.status.is_soft_blocked() {
if let Some(wake) = guard.wake {
@@ -447,8 +451,14 @@ fn select_next_context(
return Ok(Some(next_context_guard));
} else {
// We found no other process to run.
Ok(None)
let idle_context = percpu.switch_internals.idle_context();
if !Arc::ptr_eq(&prev_context_lock, &idle_context) {
// We switch into the idle context
Ok(Some(unsafe { idle_context.write_arc() }))
} else {
// We found no other process to run.
Ok(None)
}
}
}
@@ -463,6 +473,8 @@ pub struct ContextSwitchPercpu {
current_ctxt: RefCell<Option<Arc<ContextLock>>>,
/// The idle process.
idle_ctxt: RefCell<Option<Arc<ContextLock>>>,
pub(crate) being_sigkilled: Cell<bool>,
}
@@ -473,6 +485,7 @@ impl ContextSwitchPercpu {
switch_time: Cell::new(0),
pit_ticks: Cell::new(0),
current_ctxt: RefCell::new(None),
idle_ctxt: RefCell::new(None),
being_sigkilled: Cell::new(false),
}
}
@@ -513,4 +526,28 @@ impl ContextSwitchPercpu {
pub unsafe fn set_current_context(&self, new: Arc<ContextLock>) {
*self.current_ctxt.borrow_mut() = Some(new);
}
/// Sets the idle context to a new value.
///
/// # Safety
/// This function is unsafe as it modifies the idle context state directly.
///
/// # Parameters
/// - `new`: The new context to be set as the idle context.
pub unsafe fn set_idle_context(&self, new: Arc<ContextLock>) {
*self.idle_ctxt.borrow_mut() = Some(new);
}
/// Retrieves the current idle context.
///
/// # Returns
/// A reference to the idle context.
pub fn idle_context(&self) -> Arc<ContextLock> {
Arc::clone(
self.idle_ctxt
.borrow()
.as_ref()
.expect("no idle context present"),
)
}
}