Skip to content

Commit 2c004cb

Browse files
authored
support query stack info (#317)
2 parents 5cc32e1 + ae65b19 commit 2c004cb

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

core/src/coroutine/korosensei.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use crate::common::constants::CoroutineState;
33
use crate::coroutine::listener::Listener;
44
use crate::coroutine::local::CoroutineLocal;
55
use crate::coroutine::suspender::Suspender;
6+
use crate::coroutine::StackInfo;
67
use corosensei::stack::{DefaultStack, Stack};
78
use corosensei::trap::TrapHandlerRegs;
89
use corosensei::CoroutineResult;
@@ -27,7 +28,7 @@ pub struct Coroutine<'c, Param, Yield, Return> {
2728
inner: corosensei::Coroutine<Param, Yield, Result<Return, &'static str>, DefaultStack>,
2829
pub(crate) state: Cell<CoroutineState<Yield, Return>>,
2930
pub(crate) stack_size: usize,
30-
pub(crate) stack_bottom: RefCell<VecDeque<usize>>,
31+
pub(crate) stack_infos: RefCell<VecDeque<StackInfo>>,
3132
pub(crate) listeners: VecDeque<&'c dyn Listener<Yield, Return>>,
3233
pub(crate) local: CoroutineLocal<'c>,
3334
}
@@ -327,9 +328,12 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
327328
return Ok(callback());
328329
}
329330
return DefaultStack::new(stack_size).map(|stack| {
330-
co.stack_bottom.borrow_mut().push_front(stack.limit().get());
331+
co.stack_infos.borrow_mut().push_back(StackInfo {
332+
stack_top: stack.base().get(),
333+
stack_bottom: stack.limit().get(),
334+
});
331335
let r = corosensei::on_stack(stack, callback);
332-
_ = co.stack_bottom.borrow_mut().pop_front();
336+
_ = co.stack_infos.borrow_mut().pop_back();
333337
r
334338
});
335339
}
@@ -362,7 +366,10 @@ where
362366
{
363367
let stack_size = stack_size.max(crate::common::page_size());
364368
let stack = DefaultStack::new(stack_size)?;
365-
let stack_bottom = RefCell::new(VecDeque::from([stack.limit().get()]));
369+
let stack_infos = RefCell::new(VecDeque::from([StackInfo {
370+
stack_top: stack.base().get(),
371+
stack_bottom: stack.limit().get(),
372+
}]));
366373
let co_name = name.clone().leak();
367374
let inner = corosensei::Coroutine::with_stack(stack, move |y, p| {
368375
catch!(
@@ -382,7 +389,7 @@ where
382389
name,
383390
inner,
384391
stack_size,
385-
stack_bottom,
392+
stack_infos,
386393
state: Cell::new(CoroutineState::Ready),
387394
listeners: VecDeque::default(),
388395
local: CoroutineLocal::default(),

core/src/coroutine/mod.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::common::constants::CoroutineState;
22
use crate::coroutine::listener::Listener;
33
use crate::coroutine::local::CoroutineLocal;
44
use crate::{impl_current_for, impl_display_by_debug, impl_for_named};
5+
use std::collections::VecDeque;
56
use std::fmt::{Debug, Formatter};
67
use std::ops::Deref;
78

@@ -41,6 +42,18 @@ macro_rules! co {
4142
};
4243
}
4344

45+
/// The coroutine stack information.
46+
#[repr(C)]
47+
#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
48+
pub struct StackInfo {
49+
/// The base address of the stack. This is the highest address
50+
/// since stacks grow downwards on most modern architectures.
51+
pub stack_top: usize,
52+
/// The maximum limit address of the stack. This is the lowest address
53+
/// since stacks grow downwards on most modern architectures.
54+
pub stack_bottom: usize,
55+
}
56+
4457
/// Coroutine state abstraction and impl.
4558
mod state;
4659

@@ -74,7 +87,14 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
7487
/// This can only be done safely in coroutine.
7588
pub unsafe fn remaining_stack(&self) -> usize {
7689
let current_ptr = psm::stack_pointer() as usize;
77-
current_ptr - self.stack_bottom.borrow().front().copied().unwrap()
90+
current_ptr - self.stack_infos.borrow().back().unwrap().stack_bottom
91+
}
92+
93+
/// Queries the current stack info of this coroutine.
94+
///
95+
/// The first used stack index is 0 and increases with usage.
96+
pub fn stack_infos(&self) -> VecDeque<StackInfo> {
97+
self.stack_infos.borrow().clone()
7898
}
7999

80100
/// Grows the call stack if necessary.

0 commit comments

Comments
 (0)