diff --git a/core/src/co_pool/mod.rs b/core/src/co_pool/mod.rs
index a0a80eb1..5d2f8b2c 100644
--- a/core/src/co_pool/mod.rs
+++ b/core/src/co_pool/mod.rs
@@ -70,9 +70,8 @@ impl Drop for CoroutinePool<'_> {
self.get_running_size(),
"There are still tasks in progress !"
);
- assert_eq!(
- 0,
- self.task_queue.len(),
+ assert!(
+ self.task_queue.is_empty(),
"There are still tasks to be carried out !"
);
}
diff --git a/core/src/coroutine/korosensei.rs b/core/src/coroutine/korosensei.rs
index 45381406..4743e69e 100644
--- a/core/src/coroutine/korosensei.rs
+++ b/core/src/coroutine/korosensei.rs
@@ -8,7 +8,7 @@ use crate::coroutine::StackInfo;
use corosensei::stack::Stack;
use corosensei::trap::TrapHandlerRegs;
use corosensei::CoroutineResult;
-use std::cell::{Cell, RefCell};
+use std::cell::{Cell, RefCell, UnsafeCell};
use std::collections::VecDeque;
use std::ffi::c_longlong;
use std::fmt::Debug;
@@ -29,7 +29,7 @@ pub struct Coroutine<'c, Param, Yield, Return> {
pub(crate) name: String,
inner: corosensei::Coroutine, PooledStack>,
pub(crate) state: Cell>,
- pub(crate) stack_infos: RefCell>,
+ stack_infos: UnsafeCell>,
pub(crate) listeners: VecDeque<&'c dyn Listener>,
pub(crate) local: CoroutineLocal<'c>,
pub(crate) priority: Option,
@@ -291,6 +291,25 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
self.listeners.push_back(listener);
}
+ pub(crate) fn stack_infos_ref(&self) -> &VecDeque {
+ unsafe {
+ self.stack_infos
+ .get()
+ .as_ref()
+ .expect("StackInfo not init !")
+ }
+ }
+
+ #[allow(clippy::mut_from_ref)]
+ pub(crate) fn stack_infos_mut(&self) -> &mut VecDeque {
+ unsafe {
+ self.stack_infos
+ .get()
+ .as_mut()
+ .expect("StackInfo not init !")
+ }
+ }
+
/// Grows the call stack if necessary.
///
/// This function is intended to be called at manually instrumented points in a program where
@@ -314,12 +333,12 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
return Ok(callback());
}
return stack_pool.allocate(stack_size).map(|stack| {
- co.stack_infos.borrow_mut().push_back(StackInfo {
+ co.stack_infos_mut().push_back(StackInfo {
stack_top: stack.base().get(),
stack_bottom: stack.limit().get(),
});
let r = corosensei::on_stack(stack, callback);
- _ = co.stack_infos.borrow_mut().pop_back();
+ _ = co.stack_infos_mut().pop_back();
r
});
}
@@ -380,7 +399,7 @@ where
{
let stack_size = stack_size.max(crate::common::page_size());
let stack = MemoryPool::get_instance().allocate(stack_size)?;
- let stack_infos = RefCell::new(VecDeque::from([StackInfo {
+ let stack_infos = UnsafeCell::new(VecDeque::from([StackInfo {
stack_top: stack.base().get(),
stack_bottom: stack.limit().get(),
}]));
diff --git a/core/src/coroutine/mod.rs b/core/src/coroutine/mod.rs
index fcc6abc8..71aa8891 100644
--- a/core/src/coroutine/mod.rs
+++ b/core/src/coroutine/mod.rs
@@ -107,15 +107,15 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
///
/// This can only be done safely in coroutine.
pub unsafe fn remaining_stack(&self) -> usize {
- let current_ptr = psm::stack_pointer() as usize;
- current_ptr - self.stack_infos.borrow().back().unwrap().stack_bottom
+ let current_sp = psm::stack_pointer() as usize;
+ current_sp - self.stack_infos_ref().back().unwrap().stack_bottom
}
/// Queries the current stack info of this coroutine.
///
/// The first used stack index is 0 and increases with usage.
pub fn stack_infos(&self) -> VecDeque {
- self.stack_infos.borrow().clone()
+ self.stack_infos_ref().clone()
}
/// Checks whether the stack pointer at the point where a trap occurred is
@@ -126,7 +126,7 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
/// The result of this function is only meaningful if the coroutine has not
/// been dropped yet.
pub fn stack_ptr_in_bounds(&self, stack_ptr: u64) -> bool {
- for info in self.stack_infos.borrow().iter() {
+ for info in self.stack_infos_ref() {
if info.stack_bottom as u64 <= stack_ptr && stack_ptr < info.stack_top as u64 {
return true;
}
@@ -202,7 +202,7 @@ where
f.debug_struct("Coroutine")
.field("name", &self.name())
.field("state", &self.state())
- .field("stack_infos", &self.stack_infos)
+ .field("stack_infos", &self.stack_infos())
.field("local", &self.local)
.field("priority", &self.priority)
.finish()
diff --git a/core/src/coroutine/stack_pool.rs b/core/src/coroutine/stack_pool.rs
index a756e0c8..bf6c03de 100644
--- a/core/src/coroutine/stack_pool.rs
+++ b/core/src/coroutine/stack_pool.rs
@@ -186,7 +186,7 @@ impl MemoryPool {
}
pub(crate) fn allocate(&self, stack_size: usize) -> std::io::Result {
- let heap = unsafe { self.pool.get().as_mut().expect("StackPool is not unique") };
+ let heap = unsafe { self.pool.get().as_mut().expect("MemoryPool is not unique") };
// find min stack
let mut not_use = Vec::new();
while let Some(stack) = heap.peek() {
@@ -265,7 +265,7 @@ impl MemoryPool {
/// Clean the expired stack.
#[allow(dead_code)]
pub(crate) fn clean(&self) {
- let heap = unsafe { self.pool.get().as_mut().expect("StackPool is not unique") };
+ let heap = unsafe { self.pool.get().as_mut().expect("MemoryPool is not unique") };
let mut maybe_free = Vec::new();
while let Some(stack) = heap.peek() {
if Rc::strong_count(&stack.stack) > 1 {