Skip to content

Commit d5e0622

Browse files
committed
Fix a bug where cached stacks weren't re-used
The condition was the wrong direction and it also didn't take equality into account. Tests were added for both cases. For the small benchmark of `task::try(proc() {}).unwrap()`, this takes the iteration time on OSX from 15119 ns/iter to 6179 ns/iter (timed with RUST_THREADS=1) cc #11389
1 parent 89b1686 commit d5e0622

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

src/libgreen/stack.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ impl StackPool {
138138

139139
pub fn take_stack(&mut self, min_size: uint) -> Stack {
140140
// Ideally this would be a binary search
141-
match self.stacks.iter().position(|s| s.min_size < min_size) {
141+
match self.stacks.iter().position(|s| min_size <= s.min_size) {
142142
Some(idx) => self.stacks.swap_remove(idx),
143-
None => Stack::new(min_size)
143+
None => Stack::new(min_size)
144144
}
145145
}
146146

@@ -156,3 +156,33 @@ extern {
156156
end: *libc::uintptr_t) -> libc::c_uint;
157157
fn rust_valgrind_stack_deregister(id: libc::c_uint);
158158
}
159+
160+
#[cfg(test)]
161+
mod tests {
162+
use super::StackPool;
163+
164+
#[test]
165+
fn stack_pool_caches() {
166+
let mut p = StackPool::new();
167+
let s = p.take_stack(10);
168+
p.give_stack(s);
169+
let s = p.take_stack(4);
170+
assert_eq!(s.min_size, 10);
171+
p.give_stack(s);
172+
let s = p.take_stack(14);
173+
assert_eq!(s.min_size, 14);
174+
p.give_stack(s);
175+
}
176+
177+
#[test]
178+
fn stack_pool_caches_exact() {
179+
let mut p = StackPool::new();
180+
let mut s = p.take_stack(10);
181+
s.valgrind_id = 100;
182+
p.give_stack(s);
183+
184+
let s = p.take_stack(10);
185+
assert_eq!(s.min_size, 10);
186+
assert_eq!(s.valgrind_id, 100);
187+
}
188+
}

0 commit comments

Comments
 (0)