Skip to content

Commit c927e65

Browse files
committed
add stack pool
1 parent d567c96 commit c927e65

File tree

2 files changed

+23
-20
lines changed

2 files changed

+23
-20
lines changed

core/src/coroutine/korosensei.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
318318
if remaining_stack >= red_zone {
319319
return Ok(callback());
320320
}
321-
return STACK_POOL.get_stack(stack_size).map(|stack| {
321+
return STACK_POOL.allocate(stack_size).map(|stack| {
322322
co.stack_infos.borrow_mut().push_back(StackInfo {
323323
stack_top: stack.base().get(),
324324
stack_bottom: stack.limit().get(),
@@ -339,7 +339,7 @@ impl<'c, Param, Yield, Return> Coroutine<'c, Param, Yield, Return> {
339339
return Ok(callback());
340340
}
341341
}
342-
STACK_POOL.get_stack(stack_size).map(|stack| {
342+
STACK_POOL.allocate(stack_size).map(|stack| {
343343
STACK_INFOS.with(|s| {
344344
s.borrow_mut().push_back(StackInfo {
345345
stack_top: stack.base().get(),
@@ -382,7 +382,7 @@ where
382382
F: FnOnce(&Suspender<Param, Yield>, Param) -> Return + 'static,
383383
{
384384
let stack_size = stack_size.max(crate::common::page_size());
385-
let stack = STACK_POOL.get_stack(stack_size)?;
385+
let stack = STACK_POOL.allocate(stack_size)?;
386386
let stack_infos = RefCell::new(VecDeque::from([StackInfo {
387387
stack_top: stack.base().get(),
388388
stack_bottom: stack.limit().get(),

core/src/coroutine/stack_pool.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,21 @@ use std::cell::RefCell;
33
use std::cmp::Ordering;
44
use std::collections::BinaryHeap;
55
use std::ops::Deref;
6-
use std::sync::Arc;
6+
use std::rc::Rc;
77

8-
pub(crate) struct PooledStack(Arc<DefaultStack>);
8+
pub(crate) struct PooledStack(Rc<DefaultStack>);
99

1010
impl Deref for PooledStack {
11-
type Target = Arc<DefaultStack>;
11+
type Target = Rc<DefaultStack>;
1212

13-
fn deref(&self) -> &Arc<DefaultStack> {
13+
fn deref(&self) -> &Rc<DefaultStack> {
1414
&self.0
1515
}
1616
}
1717

1818
impl PartialEq<Self> for PooledStack {
1919
fn eq(&self, other: &Self) -> bool {
20-
Arc::strong_count(other).eq(&Arc::strong_count(self))
20+
Rc::strong_count(other).eq(&Rc::strong_count(self))
2121
}
2222
}
2323

@@ -32,7 +32,7 @@ impl PartialOrd<Self> for PooledStack {
3232
impl Ord for PooledStack {
3333
fn cmp(&self, other: &Self) -> Ordering {
3434
// BinaryHeap defaults to a large top heap, but we need a small top heap
35-
Arc::strong_count(other).cmp(&Arc::strong_count(self))
35+
Rc::strong_count(other).cmp(&Rc::strong_count(self))
3636
}
3737
}
3838

@@ -56,28 +56,31 @@ unsafe impl Stack for PooledStack {
5656
#[cfg(windows)]
5757
#[inline]
5858
fn update_teb_fields(&mut self, stack_limit: usize, guaranteed_stack_bytes: usize) {
59-
self.0
60-
.update_teb_fields(stack_limit, guaranteed_stack_bytes)
59+
while let Some(stack) = Rc::get_mut(&mut self) {
60+
stack.update_teb_fields(stack_limit, guaranteed_stack_bytes);
61+
return;
62+
}
6163
}
6264
}
6365

66+
/// todo `min_size` `max_size` `keep_alive_time`
6467
#[derive(Default)]
65-
pub(crate) struct StackPool(Arc<RefCell<BinaryHeap<PooledStack>>>);
68+
pub(crate) struct StackPool(RefCell<BinaryHeap<PooledStack>>);
6669

6770
unsafe impl Send for StackPool {}
6871

6972
unsafe impl Sync for StackPool {}
7073

7174
impl StackPool {
72-
pub(crate) fn get_stack(&self, stack_size: usize) -> std::io::Result<PooledStack> {
75+
pub(crate) fn allocate(&self, stack_size: usize) -> std::io::Result<PooledStack> {
7376
loop {
7477
if let Ok(mut heap) = self.0.try_borrow_mut() {
7578
if let Some(stack) = heap.peek() {
76-
if Arc::strong_count(stack) == 1 {
79+
if Rc::strong_count(stack) == 1 {
7780
return Ok(PooledStack(stack.deref().clone()));
7881
}
7982
}
80-
let stack = Arc::new(DefaultStack::new(stack_size)?);
83+
let stack = Rc::new(DefaultStack::new(stack_size)?);
8184
heap.push(PooledStack(stack.clone()));
8285
return Ok(PooledStack(stack));
8386
}
@@ -98,13 +101,13 @@ mod tests {
98101
#[test]
99102
fn test_stack_pool() -> std::io::Result<()> {
100103
let pool = StackPool::default();
101-
let stack = pool.get_stack(DEFAULT_STACK_SIZE)?;
102-
assert_eq!(Arc::strong_count(&stack), 2);
104+
let stack = pool.allocate(DEFAULT_STACK_SIZE)?;
105+
assert_eq!(Rc::strong_count(&stack), 2);
103106
drop(stack);
104-
let stack = pool.get_stack(DEFAULT_STACK_SIZE)?;
105-
assert_eq!(Arc::strong_count(&stack), 2);
107+
let stack = pool.allocate(DEFAULT_STACK_SIZE)?;
108+
assert_eq!(Rc::strong_count(&stack), 2);
106109
assert_eq!(pool.len(), 1);
107-
_ = pool.get_stack(DEFAULT_STACK_SIZE)?;
110+
_ = pool.allocate(DEFAULT_STACK_SIZE)?;
108111
assert_eq!(pool.len(), 2);
109112
Ok(())
110113
}

0 commit comments

Comments
 (0)