Unify context list again now that we have a run queue
This simplifies code and ensures that exiting a context will properly remove it from the list of contexts.
This commit is contained in:
+12
-15
@@ -72,13 +72,7 @@ pub use self::arch::empty_cr3;
|
||||
|
||||
// Set of weak references to all contexts available for scheduling. The only strong references are
|
||||
// the context file descriptors.
|
||||
static CONTEXTS: Mutex<L2, BTreeSet<ContextRef>> = Mutex::new(BTreeSet::new());
|
||||
/// Try to get the global free contexts
|
||||
pub fn free_contexts_try(
|
||||
token: LockToken<'_, L1>,
|
||||
) -> Option<MutexGuard<'_, L2, BTreeSet<ContextRef>>> {
|
||||
CONTEXTS.try_lock(token)
|
||||
}
|
||||
static CONTEXTS: RwLock<L2, BTreeSet<ContextRef>> = RwLock::new(BTreeSet::new());
|
||||
|
||||
// Actual context store for the scheduler
|
||||
static RUN_CONTEXTS: Mutex<L1, RunContextData> = Mutex::new(RunContextData::new());
|
||||
@@ -97,15 +91,13 @@ impl RunContextData {
|
||||
}
|
||||
|
||||
/// Get the global schemes list, const
|
||||
pub fn contexts(token: LockToken<'_, L0>) -> RwLockReadGuard<'_, L1, BTreeSet<ContextRef>> {
|
||||
let percpu = PercpuBlock::current();
|
||||
percpu.contexts.read(token)
|
||||
pub fn contexts(token: LockToken<'_, L1>) -> RwLockReadGuard<'_, L2, BTreeSet<ContextRef>> {
|
||||
CONTEXTS.read(token)
|
||||
}
|
||||
|
||||
/// Get per cpu contexts, mutable
|
||||
pub fn contexts_mut(token: LockToken<'_, L0>) -> RwLockWriteGuard<'_, L1, BTreeSet<ContextRef>> {
|
||||
let percpu = PercpuBlock::current();
|
||||
percpu.contexts.write(token)
|
||||
pub fn contexts_mut(token: LockToken<'_, L1>) -> RwLockWriteGuard<'_, L2, BTreeSet<ContextRef>> {
|
||||
CONTEXTS.write(token)
|
||||
}
|
||||
|
||||
pub fn run_contexts(token: LockToken<'_, L0>) -> MutexGuard<'_, L1, RunContextData> {
|
||||
@@ -128,10 +120,12 @@ pub fn init(token: &mut CleanLockToken) {
|
||||
context.cpu_id = Some(crate::cpu_id());
|
||||
context.enqueued = false;
|
||||
|
||||
let priority = context.prio;
|
||||
|
||||
let context_lock = Arc::new(ContextLock::new(context));
|
||||
|
||||
let context_ref = ContextRef(Arc::clone(&context_lock));
|
||||
contexts_mut(token.token()).insert(context_ref);
|
||||
contexts_mut(token.token().downgrade()).insert(context_ref.clone());
|
||||
|
||||
unsafe {
|
||||
let percpu = PercpuBlock::current();
|
||||
@@ -139,6 +133,8 @@ pub fn init(token: &mut CleanLockToken) {
|
||||
.switch_internals
|
||||
.set_current_context(Arc::clone(&context_lock));
|
||||
}
|
||||
|
||||
run_contexts(token.downgrade()).set[priority].push_back(context_ref);
|
||||
}
|
||||
|
||||
pub fn wakeup_context(context_lock: &Arc<RwLock<L4, Context>>, mut token: LockToken<L0>) {
|
||||
@@ -176,6 +172,7 @@ pub fn is_current(context: &Arc<ContextLock>) -> bool {
|
||||
.with_context(|current| Arc::ptr_eq(context, current))
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ContextRef(pub Arc<ContextLock>);
|
||||
impl ContextRef {
|
||||
pub fn upgrade(&self) -> Option<Arc<ContextLock>> {
|
||||
@@ -224,7 +221,7 @@ pub fn spawn(
|
||||
|
||||
let run_ref = ContextRef(Arc::clone(&context_lock));
|
||||
run_contexts(token.token()).set[20].push_back(run_ref);
|
||||
contexts_mut(token.token()).insert(context_ref);
|
||||
contexts_mut(token.token().downgrade()).insert(context_ref);
|
||||
context_lock.write(token.token()).enqueued = true;
|
||||
|
||||
Ok(context_lock)
|
||||
|
||||
+4
-26
@@ -3,10 +3,7 @@
|
||||
//! handling process states and synchronization.
|
||||
|
||||
use crate::{
|
||||
context::{
|
||||
self, arch, contexts, contexts_mut, free_contexts_try, run_contexts,
|
||||
ArcContextLockWriteGuard, Context, ContextLock,
|
||||
},
|
||||
context::{self, arch, contexts, run_contexts, ArcContextLockWriteGuard, Context, ContextLock},
|
||||
cpu_set::LogicalCpuId,
|
||||
cpu_stats::{self, CpuState},
|
||||
percpu::PercpuBlock,
|
||||
@@ -176,12 +173,12 @@ pub fn switch(token: &mut CleanLockToken) -> SwitchResult {
|
||||
}
|
||||
|
||||
// Alarm (previously in update_runnable)
|
||||
// TODO: Optimise this somehow
|
||||
// TODO: Optimise this somehow. Perhaps using a separate timer queue?
|
||||
let mut wakeups = Vec::new();
|
||||
{
|
||||
let current_context = context::current();
|
||||
|
||||
let mut contexts_guard = contexts(token.token());
|
||||
let mut contexts_guard = contexts(token.downgrade());
|
||||
let (context, mut token) = contexts_guard.token_split();
|
||||
for context_ref in context.iter().filter_map(|r| r.upgrade()) {
|
||||
if Arc::ptr_eq(&context_ref, ¤t_context) {
|
||||
@@ -214,7 +211,7 @@ pub fn switch(token: &mut CleanLockToken) -> SwitchResult {
|
||||
let was_idle = percpu.stats.add_time(percpu_ms) == CpuState::Idle as u8;
|
||||
percpu.switch_internals.switch_time.set(switch_time);
|
||||
|
||||
let mut switch_context_opt = match select_next_context(
|
||||
let switch_context_opt = match select_next_context(
|
||||
token,
|
||||
percpu,
|
||||
cpu_id,
|
||||
@@ -226,25 +223,6 @@ pub fn switch(token: &mut CleanLockToken) -> SwitchResult {
|
||||
Err(early_ret) => return early_ret,
|
||||
};
|
||||
|
||||
if switch_context_opt.is_none() {
|
||||
let mut this_contexts = contexts_mut(token.token());
|
||||
let (this_contexts, mut token) = this_contexts.token_split();
|
||||
if let Some(mut free_contexts) = free_contexts_try(token.token())
|
||||
&& let Some(context) = free_contexts.pop_last()
|
||||
{
|
||||
// Check if we can run this free context immediately
|
||||
if let Some(next_context) = context.upgrade() {
|
||||
let mut next_context_guard = unsafe { next_context.write_arc() };
|
||||
if let UpdateResult::CanSwitch =
|
||||
unsafe { update_runnable(&mut next_context_guard, cpu_id, switch_time) }
|
||||
{
|
||||
switch_context_opt = Some(next_context_guard);
|
||||
}
|
||||
}
|
||||
this_contexts.insert(context);
|
||||
}
|
||||
}
|
||||
|
||||
// Switch process states, TSS stack pointer, and store new context ID
|
||||
match switch_context_opt {
|
||||
Some(mut next_context_guard) => {
|
||||
|
||||
+125
-122
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
context::{context::SyscallFrame, Context, ContextLock},
|
||||
context::{context::SyscallFrame, contexts, Context, ContextLock},
|
||||
memory::{
|
||||
get_page_info, the_zeroed_frame, Frame, RefCount, RmmA, RmmArch, TableKind, PAGE_SIZE,
|
||||
},
|
||||
@@ -20,154 +20,157 @@ pub unsafe fn debugger(target_id: Option<*const ContextLock>, token: &mut CleanL
|
||||
|
||||
let old_table = RmmA::table(TableKind::User);
|
||||
|
||||
let contexts = crate::percpu::get_all_contexts(token.downgrade());
|
||||
for context_arc in contexts.iter() {
|
||||
if target_id.map_or(false, |target_id| Arc::as_ptr(&context_arc) != target_id) {
|
||||
continue;
|
||||
}
|
||||
let context = context_arc.read(token.token());
|
||||
println!("{:p}: {}", Arc::as_ptr(&context_arc), context.name);
|
||||
{
|
||||
let mut contexts = contexts(token.downgrade());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_arc in contexts.iter().filter_map(|x| x.upgrade()) {
|
||||
if target_id.map_or(false, |target_id| Arc::as_ptr(&context_arc) != target_id) {
|
||||
continue;
|
||||
}
|
||||
let context = context_arc.read(token.token());
|
||||
println!("{:p}: {}", Arc::as_ptr(&context_arc), context.name);
|
||||
|
||||
let mut mark_frame_use = |frame| {
|
||||
tree.entry(frame).or_insert((0, false)).0 += 1;
|
||||
};
|
||||
let mut mark_frame_use = |frame| {
|
||||
tree.entry(frame).or_insert((0, false)).0 += 1;
|
||||
};
|
||||
|
||||
match &context.syscall_head {
|
||||
SyscallFrame::Free(head) => mark_frame_use(head.get()),
|
||||
SyscallFrame::Used { _frame: head } => mark_frame_use(*head),
|
||||
SyscallFrame::Dummy => {}
|
||||
}
|
||||
match &context.syscall_tail {
|
||||
SyscallFrame::Free(tail) => mark_frame_use(tail.get()),
|
||||
SyscallFrame::Used { _frame: tail } => mark_frame_use(*tail),
|
||||
SyscallFrame::Dummy => {}
|
||||
}
|
||||
match &context.syscall_head {
|
||||
SyscallFrame::Free(head) => mark_frame_use(head.get()),
|
||||
SyscallFrame::Used { _frame: head } => mark_frame_use(*head),
|
||||
SyscallFrame::Dummy => {}
|
||||
}
|
||||
match &context.syscall_tail {
|
||||
SyscallFrame::Free(tail) => mark_frame_use(tail.get()),
|
||||
SyscallFrame::Used { _frame: tail } => mark_frame_use(*tail),
|
||||
SyscallFrame::Dummy => {}
|
||||
}
|
||||
|
||||
if let Some(sig) = &context.sig {
|
||||
mark_frame_use(sig.proc_control.get());
|
||||
mark_frame_use(sig.thread_control.get());
|
||||
}
|
||||
if let Some(sig) = &context.sig {
|
||||
mark_frame_use(sig.proc_control.get());
|
||||
mark_frame_use(sig.thread_control.get());
|
||||
}
|
||||
|
||||
// TODO: Lock ordering violation
|
||||
let mut token = unsafe { CleanLockToken::new() };
|
||||
// TODO: Lock ordering violation
|
||||
let mut token = unsafe { CleanLockToken::new() };
|
||||
|
||||
// Switch to context page table to ensure syscall debug and stack dump will work
|
||||
if let Some(ref space) = context.addr_space {
|
||||
let was_new = spaces.insert(
|
||||
space
|
||||
.acquire_read(token.downgrade())
|
||||
.table
|
||||
.utable
|
||||
.table()
|
||||
.phys()
|
||||
.data(),
|
||||
);
|
||||
unsafe {
|
||||
RmmA::set_table(
|
||||
TableKind::User,
|
||||
// Switch to context page table to ensure syscall debug and stack dump will work
|
||||
if let Some(ref space) = context.addr_space {
|
||||
let was_new = spaces.insert(
|
||||
space
|
||||
.acquire_read(token.downgrade())
|
||||
.table
|
||||
.utable
|
||||
.table()
|
||||
.phys(),
|
||||
.phys()
|
||||
.data(),
|
||||
);
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
check_page_table_consistency(
|
||||
&mut space.acquire_write(token.downgrade()),
|
||||
was_new,
|
||||
&mut tree,
|
||||
unsafe {
|
||||
RmmA::set_table(
|
||||
TableKind::User,
|
||||
space
|
||||
.acquire_read(token.downgrade())
|
||||
.table
|
||||
.utable
|
||||
.table()
|
||||
.phys(),
|
||||
);
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
check_page_table_consistency(
|
||||
&mut space.acquire_write(token.downgrade()),
|
||||
was_new,
|
||||
&mut tree,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
println!("status: {:?}", context.status);
|
||||
if !context.status_reason.is_empty() {
|
||||
println!("reason: {}", context.status_reason);
|
||||
}
|
||||
if let Some([a, b, c, d, e, f, g]) = context.current_syscall() {
|
||||
println!(
|
||||
"syscall: {}",
|
||||
crate::syscall::debug::format_call(a, b, c, d, e, f, g)
|
||||
);
|
||||
}
|
||||
}
|
||||
if let Some(ref addr_space) = context.addr_space {
|
||||
let addr_space = addr_space.acquire_read(token.downgrade());
|
||||
if !addr_space.grants.is_empty() {
|
||||
println!("grants:");
|
||||
for (base, info) in addr_space.grants.iter() {
|
||||
let size = info.page_count() * PAGE_SIZE;
|
||||
|
||||
println!("status: {:?}", context.status);
|
||||
if !context.status_reason.is_empty() {
|
||||
println!("reason: {}", context.status_reason);
|
||||
}
|
||||
if let Some([a, b, c, d, e, f, g]) = context.current_syscall() {
|
||||
println!(
|
||||
"syscall: {}",
|
||||
crate::syscall::debug::format_call(a, b, c, d, e, f, g)
|
||||
);
|
||||
}
|
||||
if let Some(ref addr_space) = context.addr_space {
|
||||
let addr_space = addr_space.acquire_read(token.downgrade());
|
||||
if !addr_space.grants.is_empty() {
|
||||
println!("grants:");
|
||||
for (base, info) in addr_space.grants.iter() {
|
||||
let size = info.page_count() * PAGE_SIZE;
|
||||
let flags = format_args!(
|
||||
"{}{}{}{}",
|
||||
if info.flags().has_user() { "u" } else { "k" },
|
||||
if info.flags().has_present() { "r" } else { "-" },
|
||||
if info.flags().has_write() { "w" } else { "-" },
|
||||
if info.flags().has_execute() { "x" } else { "-" },
|
||||
);
|
||||
|
||||
let flags = format_args!(
|
||||
"{}{}{}{}",
|
||||
if info.flags().has_user() { "u" } else { "k" },
|
||||
if info.flags().has_present() { "r" } else { "-" },
|
||||
if info.flags().has_write() { "w" } else { "-" },
|
||||
if info.flags().has_execute() { "x" } else { "-" },
|
||||
);
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
println!(
|
||||
" virt 0x{:016x}:0x{:016x} {} size 0x{:08x} {:?}",
|
||||
base.start_address().data(),
|
||||
base.next_by(info.page_count() - 1).start_address().data() + 0xFFF,
|
||||
flags,
|
||||
size,
|
||||
info.provider,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
println!(
|
||||
" virt 0x{:016x}:0x{:016x} {} size 0x{:08x} {:?}",
|
||||
base.start_address().data(),
|
||||
base.next_by(info.page_count() - 1).start_address().data() + 0xFFF,
|
||||
flags,
|
||||
size,
|
||||
info.provider,
|
||||
);
|
||||
// FIXME riscv64 implementation
|
||||
|
||||
// FIXME riscv64 implementation
|
||||
#[cfg(target_arch = "x86")]
|
||||
println!(
|
||||
" virt 0x{:08x}:0x{:08x} {} size 0x{:08x} {:?}",
|
||||
base.start_address().data(),
|
||||
base.next_by(info.page_count()).start_address().data() + 0xFFF,
|
||||
flags,
|
||||
size,
|
||||
info.provider,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
println!(
|
||||
" virt 0x{:08x}:0x{:08x} {} size 0x{:08x} {:?}",
|
||||
base.start_address().data(),
|
||||
base.next_by(info.page_count()).start_address().data() + 0xFFF,
|
||||
flags,
|
||||
size,
|
||||
info.provider,
|
||||
);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
println!(
|
||||
" virt 0x{:016x}:0x{:016x} {} size 0x{:08x} {:?}",
|
||||
base.start_address().data(),
|
||||
base.start_address().data() + size - 1,
|
||||
flags,
|
||||
size,
|
||||
info.provider,
|
||||
);
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
println!(
|
||||
" virt 0x{:016x}:0x{:016x} {} size 0x{:08x} {:?}",
|
||||
base.start_address().data(),
|
||||
base.start_address().data() + size - 1,
|
||||
flags,
|
||||
size,
|
||||
info.provider,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(regs) = context.regs() {
|
||||
println!("regs:");
|
||||
regs.dump();
|
||||
if let Some(regs) = context.regs() {
|
||||
println!("regs:");
|
||||
regs.dump();
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
dump_stack(&*context, regs.iret.sp_el0);
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
dump_stack(&*context, regs.iret.sp_el0);
|
||||
|
||||
// FIXME riscv64 implementation
|
||||
// FIXME riscv64 implementation
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
dump_stack(&*context, regs.iret.esp);
|
||||
#[cfg(target_arch = "x86")]
|
||||
dump_stack(&*context, regs.iret.esp);
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
unsafe {
|
||||
x86::bits64::rflags::stac();
|
||||
}
|
||||
dump_stack(&*context, regs.iret.rsp);
|
||||
unsafe {
|
||||
x86::bits64::rflags::clac();
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
unsafe {
|
||||
x86::bits64::rflags::stac();
|
||||
}
|
||||
dump_stack(&*context, regs.iret.rsp);
|
||||
unsafe {
|
||||
x86::bits64::rflags::clac();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Switch to original page table
|
||||
unsafe { RmmA::set_table(TableKind::User, old_table) };
|
||||
|
||||
println!();
|
||||
}
|
||||
|
||||
// Switch to original page table
|
||||
unsafe { RmmA::set_table(TableKind::User, old_table) };
|
||||
|
||||
println!();
|
||||
}
|
||||
#[cfg(any(target_arch = "aarch64", target_arch = "x86_64"))]
|
||||
crate::scheme::proc::foreach_addrsp(token, |addrsp, mut token| {
|
||||
|
||||
+2
-22
@@ -1,5 +1,4 @@
|
||||
use alloc::{
|
||||
collections::BTreeSet,
|
||||
sync::{Arc, Weak},
|
||||
vec::Vec,
|
||||
};
|
||||
@@ -13,13 +12,11 @@ use syscall::PtraceFlags;
|
||||
|
||||
use crate::{
|
||||
arch::device::ArchPercpuMisc,
|
||||
context::{
|
||||
empty_cr3, memory::AddrSpaceWrapper, switch::ContextSwitchPercpu, ContextLock, ContextRef,
|
||||
},
|
||||
context::{empty_cr3, memory::AddrSpaceWrapper, switch::ContextSwitchPercpu},
|
||||
cpu_set::{LogicalCpuId, MAX_CPU_COUNT},
|
||||
cpu_stats::{CpuStats, CpuStatsData},
|
||||
ptrace::Session,
|
||||
sync::{CleanLockToken, LockToken, RwLock, L1},
|
||||
sync::CleanLockToken,
|
||||
syscall::debug::SyscallDebugInfo,
|
||||
};
|
||||
|
||||
@@ -50,7 +47,6 @@ pub struct PercpuBlock {
|
||||
pub misc_arch_info: crate::arch::device::ArchPercpuMisc,
|
||||
|
||||
pub stats: CpuStats,
|
||||
pub contexts: RwLock<L1, BTreeSet<ContextRef>>,
|
||||
}
|
||||
|
||||
static ALL_PERCPU_BLOCKS: [AtomicPtr<PercpuBlock>; MAX_CPU_COUNT as usize] =
|
||||
@@ -74,21 +70,6 @@ pub fn get_all_stats() -> Vec<(LogicalCpuId, CpuStatsData)> {
|
||||
res
|
||||
}
|
||||
|
||||
/// Get copy of all cpu ref contexts
|
||||
pub fn get_all_contexts(mut token: LockToken<'_, L1>) -> Vec<Arc<ContextLock>> {
|
||||
let mut all_contexts = Vec::new();
|
||||
for block in ALL_PERCPU_BLOCKS
|
||||
.iter()
|
||||
.filter_map(|block| unsafe { block.load(Ordering::Relaxed).as_ref() })
|
||||
{
|
||||
// TODO: When load balancer implemented, contexts need to be locked altogether
|
||||
// TODO: Lock token violation, downgrade this to L2 later
|
||||
let contexts = unsafe { &block.contexts.reupgradeable_read(token.token()) };
|
||||
all_contexts.extend(contexts.iter().filter_map(|x| x.upgrade()));
|
||||
}
|
||||
all_contexts
|
||||
}
|
||||
|
||||
// PercpuBlock::current() is implemented somewhere in the arch-specific modules
|
||||
|
||||
pub fn shootdown_tlb_ipi(target: Option<LogicalCpuId>) {
|
||||
@@ -219,7 +200,6 @@ impl PercpuBlock {
|
||||
misc_arch_info: ArchPercpuMisc::default(),
|
||||
|
||||
stats: CpuStats::default(),
|
||||
contexts: RwLock::new(BTreeSet::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use alloc::{string::String, vec::Vec};
|
||||
use core::fmt::Write;
|
||||
|
||||
use crate::{percpu, sync::CleanLockToken, syscall::error::Result};
|
||||
use crate::{context::contexts, sync::CleanLockToken, syscall::error::Result};
|
||||
|
||||
pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
let mut string = String::new();
|
||||
@@ -9,8 +9,9 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
{
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
let contexts = percpu::get_all_contexts(token.downgrade());
|
||||
for context_lock in contexts {
|
||||
let mut contexts = contexts(token.downgrade());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_lock in contexts.iter().filter_map(|x| x.upgrade()) {
|
||||
let context = context_lock.read(token.token());
|
||||
rows.push((context.pid, context.name, context.status_reason));
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use alloc::{
|
||||
};
|
||||
use core::fmt::Write;
|
||||
|
||||
use crate::{context, percpu, sync::CleanLockToken, syscall::error::Result};
|
||||
use crate::{context, context::contexts, sync::CleanLockToken, syscall::error::Result};
|
||||
|
||||
pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
let mut string = format!(
|
||||
@@ -15,8 +15,9 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
let contexts = percpu::get_all_contexts(token.downgrade());
|
||||
for context_ref in contexts {
|
||||
let mut contexts = contexts(token.downgrade());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_ref in contexts.iter().filter_map(|x| x.upgrade()) {
|
||||
let context = context_ref.read(token.token());
|
||||
let addr_space = context.addr_space().map(|a| a.clone());
|
||||
|
||||
@@ -35,7 +36,7 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
|
||||
let heap = match addr_space {
|
||||
Ok(addr_space) => {
|
||||
let addr_space_guard = addr_space.acquire_read(token.downgrade());
|
||||
let addr_space_guard = addr_space.acquire_read(token.token());
|
||||
let mut private_memory = 0;
|
||||
let mut shared_memory = 0;
|
||||
// TODO: All user programs must have some grant in order for executable memory to even
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use crate::{
|
||||
alloc::string::ToString,
|
||||
context::{file::LockedFileDescription, memory::AddrSpaceWrapper},
|
||||
percpu,
|
||||
context::{contexts, file::LockedFileDescription, memory::AddrSpaceWrapper},
|
||||
scheme::{self, handles, KernelSchemes},
|
||||
sync::CleanLockToken,
|
||||
syscall::error::Result,
|
||||
@@ -37,7 +36,9 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
let mut schemes_guard = handles().read(token.token());
|
||||
let (schemes, mut token) = schemes_guard.token_split();
|
||||
|
||||
'contexts: for context in percpu::get_all_contexts(token.token()) {
|
||||
let mut contexts = contexts(token.token());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
'contexts: for context in contexts.iter().filter_map(|x| x.upgrade()) {
|
||||
let mut context_guard = context.read(token.token());
|
||||
let (context, token) = context_guard.token_split();
|
||||
let mut files_guard = context.files.read(token);
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
memory::{Grant, PageSpan},
|
||||
},
|
||||
memory::PAGE_SIZE,
|
||||
percpu, scheme,
|
||||
scheme,
|
||||
sync::CleanLockToken,
|
||||
syscall::{
|
||||
error::Result,
|
||||
@@ -22,7 +22,9 @@ fn inner(fpath_user: UserSliceRw, token: &mut CleanLockToken) -> Result<Vec<u8>>
|
||||
{
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
for context_ref in percpu::get_all_contexts(token.downgrade()) {
|
||||
let mut contexts = context::contexts(token.downgrade());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_ref in contexts.iter().filter_map(|x| x.upgrade()) {
|
||||
let mut current = context_ref.read(token.token());
|
||||
let (context, mut token) = current.token_split();
|
||||
rows.push((
|
||||
|
||||
+11
-6
@@ -1,9 +1,9 @@
|
||||
use core::fmt::Write as _;
|
||||
|
||||
use crate::{
|
||||
context::Status,
|
||||
context::{contexts, Status},
|
||||
cpu_stats::{get_context_switch_count, get_contexts_count, irq_counts},
|
||||
percpu::{self, get_all_stats},
|
||||
percpu::get_all_stats,
|
||||
sync::CleanLockToken,
|
||||
syscall::error::Result,
|
||||
time::START,
|
||||
@@ -76,10 +76,15 @@ fn get_contexts_stats(token: &mut CleanLockToken) -> (u64, u64) {
|
||||
let mut running = 0;
|
||||
let mut blocked = 0;
|
||||
|
||||
let statuses = percpu::get_all_contexts(token.downgrade())
|
||||
.iter()
|
||||
.map(|context| context.read(token.token()).status.clone())
|
||||
.collect::<Vec<_>>();
|
||||
let statuses = {
|
||||
let mut contexts = contexts(token.downgrade());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
contexts
|
||||
.iter()
|
||||
.filter_map(|x| x.upgrade())
|
||||
.map(|context| context.read(token.token()).status.clone())
|
||||
.collect::<Vec<_>>()
|
||||
};
|
||||
|
||||
for status in statuses {
|
||||
if matches!(status, Status::Runnable) {
|
||||
|
||||
@@ -2,7 +2,7 @@ use alloc::{string::String, vec::Vec};
|
||||
use core::fmt::Write;
|
||||
|
||||
use crate::{
|
||||
percpu,
|
||||
context::contexts,
|
||||
sync::CleanLockToken,
|
||||
syscall::{self, error::Result},
|
||||
};
|
||||
@@ -13,7 +13,9 @@ pub fn resource(token: &mut CleanLockToken) -> Result<Vec<u8>> {
|
||||
{
|
||||
let mut rows = Vec::new();
|
||||
{
|
||||
for context_ref in percpu::get_all_contexts(token.downgrade()) {
|
||||
let mut contexts = contexts(token.downgrade());
|
||||
let (contexts, mut token) = contexts.token_split();
|
||||
for context_ref in contexts.iter().filter_map(|x| x.upgrade()) {
|
||||
let context = context_ref.read(token.token());
|
||||
rows.push((context.pid, context.name, context.current_syscall()));
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ pub fn exit_this_context(excp: Option<syscall::Exception>, token: &mut CleanLock
|
||||
);
|
||||
}
|
||||
{
|
||||
if !context::contexts_mut(token.token()).remove(&ContextRef(context_lock)) {
|
||||
if !context::contexts_mut(token.downgrade()).remove(&ContextRef(context_lock)) {
|
||||
#[cfg(feature = "drop_panic")]
|
||||
{
|
||||
panic!("This context is not in the cpu")
|
||||
|
||||
Reference in New Issue
Block a user