Skip to content

Commit 4e1fdc8

Browse files
authored
Add Fiber::Stack#size (#16420)
A tiny refactor to save the stack size in the `Fiber::Stack` object, so we can free stacks without assuming the stack's actual size. This is a preparation for thread pool, which has to free stacks outside of execution contexts and thus outside any stack pool, for example.
1 parent 6bb4d99 commit 4e1fdc8

File tree

2 files changed

+15
-5
lines changed

2 files changed

+15
-5
lines changed

src/fiber/stack.cr

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,19 @@ class Fiber
33
struct Stack
44
getter pointer : Void*
55
getter bottom : Void*
6+
getter size : Int32
67
getter? reusable : Bool
78

8-
def initialize(@pointer, @bottom, *, @reusable = false)
9+
# Constructor for thread stacks (main fibers).
10+
def initialize(@pointer : Void*, @bottom : Void*, *, @reusable = false)
11+
# FIXME: sometimes gc/boehm reports weird stack limits on linux (over
12+
# 2GB) at least, so we always cast to i32 without overflow checks.
13+
@size = (@bottom - @pointer).to_i32!
14+
end
15+
16+
# Constructor for fiber stacks.
17+
def initialize(@pointer : Void*, @size : Int32, *, @reusable = false)
18+
@bottom = @pointer + @size
919
end
1020

1121
def first_addressable_pointer : Void**

src/fiber/stack_pool.cr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Fiber
2626

2727
def finalize
2828
@deque.each do |stack|
29-
Crystal::System::Fiber.free_stack(stack.pointer, STACK_SIZE)
29+
Crystal::System::Fiber.free_stack(stack.pointer, stack.size)
3030
end
3131
end
3232

@@ -35,7 +35,7 @@ class Fiber
3535
def collect(count = lazy_size // 2) : Nil
3636
count.times do
3737
if stack = shift?
38-
Crystal::System::Fiber.free_stack(stack.pointer, STACK_SIZE)
38+
Crystal::System::Fiber.free_stack(stack.pointer, stack.size)
3939
else
4040
return
4141
end
@@ -52,11 +52,11 @@ class Fiber
5252
# Removes a stack from the bottom of the pool, or allocates a new one.
5353
def checkout : Stack
5454
if stack = pop?
55-
Crystal::System::Fiber.reset_stack(stack.pointer, STACK_SIZE, @protect)
55+
Crystal::System::Fiber.reset_stack(stack.pointer, stack.size, @protect)
5656
stack
5757
else
5858
pointer = Crystal::System::Fiber.allocate_stack(STACK_SIZE, @protect)
59-
Stack.new(pointer, pointer + STACK_SIZE, reusable: true)
59+
Stack.new(pointer, STACK_SIZE, reusable: true)
6060
end
6161
end
6262

0 commit comments

Comments
 (0)