Andrei Alexandrescu wrote:
Georg Wrede wrote:
Andrei Alexandrescu wrote:
Computing the stack depth even for non-recursive functions is an
interprocedural analysis so it's difficult to do modularly. The stack
is also unchecked so going with a "good enough" approximation is
bound to be risky.
The old size estimation problem. No matter how big you decide on,
somewhere is an idiot who will blow that size too.
A runtime solution just occurred to me. The newly allocated stack for
a thread is zeroed first, right? Well then, just before the thread
finishes, one could scan the stack area, and find the first address
that contains a non-zero value.
This isn't bullet proof in theory, but hey, the aim is to help in
/estimating/ the needed stack size.
You can't be more serious than Mark Twain when giving advice on the
stock market: "Buy some stock. If it goes up, sell it. If it doesn't go
up, don't buy it."
I'd be amazed if the stack usage of hello.d varied from run to run.
Incidentally, this raises another thought: what if the stack was
extendable? Like D arrays? A stack overflow would trigger a relocation
of the stack, and then continue. Being able to have hundreds of small
stacks would be useful in other things than threads, too.
That would be great. I don't know whether it can be done.
Two methods come to mind.(1)
By the way, I think you're underestimating how much stack the OS gives
to the stack. On my system:
$ grep PTHREAD_STACK /usr/include/**/*.h
/usr/include/bits/local_lim.h:#define PTHREAD_STACK_MIN 16384
/usr/include/pthread.h: minimal size of the block must be
PTHREAD_STACK_MIN.*/
/usr/include/pthread.h: to be started. This size must never be less
than PTHREAD_STACK_MIN
Seems like that minimum means the OS won't start a new thread with less
[stack] space left on the computer. Gotta be /some/ value, big enough to
be fine with virtually any app.
You can't have a stack smaller than 16KB as far as I understand. I seem
to recall the default stack size is much bigger.
Totally not having researched this... The page
http://www.unix.com/high-level-programming/34632-how-find-out-stack-size-occupied-process.html
states that "Most Linux systems have no stack limits set" (didn't have
time to find a definitive reference, yet).
Also, PTHREAD_STACK_MIN would be the main process stack size. If we're
running co-operative multitasking, or continuations or some such, then
the other stacks really can be smaller.
The important thing to know is, does "somebody else" than our program
use the current stack? If not, then we're free to allocate "just enough"
(in practice much more) to the stacks. IIUC, our stack is only used by
our app, its library calls, and the OS API calls.
(1) Using several stacks:
What does one need to use several stacks? Let's assume we have the
"regular" stack, and then we temporarily want to use another.
First we allocate space for the new stack. Then we disable interrupts,
(we could even save processor state), change the stack pointer to point
to the new stack. Enable interrupts, and go on with the program (i.e.
call the routine we want to have using the new stack). Once it finishes,
disable interrupts, reset the stack pointer, enable interrupts.
Knowing in advance the needed stack space helps here. Especially if
instances of the same code are to run with each stack, then all we need
is an array of stack spaces. :-)
The other thing: suppose we really don't know the stack usage. Then each
routine can use the same stack while it runs, and at task switch we copy
the actually used portion of the stack to the heap. Next time we want to
run that task, we copy the data back from the heap.
I admit this isn't done in an evening, but it's doable.