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.

Reply via email to