How do I know how much stack space FnOnce needs?

How do I know how much stack space FnOnce needs?

for example:
let f = || {
let x1 = [42u8; 50000];
let x2 = [42u8; 50000];
let x3 = [42u8; 50000];
let x4 = [42u8; 50000];
let x5 = [42u8; 50000];
let x6 = [42u8; 50000];
};

let stack_size = f.get_stack_size() ??

There's no easy way to predict the amount of stack space a particular function would use.

2 Likes

The stacker crate may be of use to you, depending on what you need to do.

1 Like

Stacker knows how much space is left, but cannot predict how much space the function needs

I want to know how much space a function is expected to need in order to decide whether to allocate stack or heap memory

Is there a way to customize memory allocation?

I think you have to allow a large margin, for reasons I don't understand.

Here it says: "// Grow the stack if we are within the "red zone" of 32K"

What the "red zone" is I don't know.

red zone means that when the stack free space reaches this value, the function is allocated to the heap space。When the remaining space has this value, it indicates that the area is a red line and cannot exceed the reserved space

As @alice says, Rust doesn't have a way to predict stack space. And as long as it allows unrestricted recursion, I'm not sure how it could.

If you'd like to share more about your use case, maybe we can come up with an alternative solution that can help.

1 Like

First to note that It is likely this is an XY problem.
You cannot solve the problem, because the problem is equivalent to the halting problem in general. But there are possible approaches under some assumptions.

An approach is to tell the compiler to generate annotations of the stack usage.
Apparently, LLVM has some support of emitting stack usage https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fstack-usage but I'm not sure it can be adopted for a Rust program.

It may also be possible to get some information from the debug information.

1 Like

i see this Introduction - Green Threads Explained in 200 Lines of Rust

Green threads are much easier to write concurrently than something like Tokio. Like Golang. Unlike Golang, Rust does not allow stack migration, but it may be possible to allocate to the heap using a scheme like Stacker

I am looking for whether there is a feasible plan, set a pre-allocated stack space (space allocation when judging function need enough, if enough direct execution, if not assigned to the heap) it is hard to solve the problem is that we don't know Fn need to how much space, can only be used for current has much space

I think you could just allocate a buffer of some large fixed size.
In typical environment, physical memory is not used until the memory is actually accessed, so the total number of allocations can be large.

There are some other issues with stackful coroutines in Rust, though.
An existing implementation of stackful coroutine is https://github.com/Xudong-Huang/may.

Some of the reasons that predicting stack usage is complicated is dynamic dispatch and recursion. With dynamic dispatch, you are calling functions that you don't know about up front, so there's no way to know their stack usage, and with recursion, you also can't predict it without knowing how many times it will recursively call itself, which can also be hard to predict.

Interestingly, with async/await, the future object itself, which stores all variables that are held alive across a yield point, does have a specific, known-in-advance type, which Rust can do because async/await is compiled entirely differently. Hence, Tokio can allocate exactly the amount of memory needed to store the future object. Still, this might not be enough because anything that happens between yield points still uses the ordinary stack, and cannot be predicted.

4 Likes

Suppose the fixed allocation of space is 2KB (the same as the initial golang value), but when the user starts the first green thread and applies for a 4KB stack or more (we only know that there is 2KB left), panic occurs instead of normal execution

What I suggested is using a larger stack limit, comparable to the typical thread default stack size (or use that value).
Yes stack overflow can still occur, but stack overflow also occurs in the default stack (normal execution), so it is fine for most programs.

This seems like an insurmountable problem。

I know what you mean. What you mean is that we use thread stack space and allocate a limited stack space to the function.

Knowing the exact stack space size the function needs without actual execution, is isomorphic to the halting problem. You can translate all the loops in the function with recursions - which uses finite stack space iff it halts.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.