Page 1 of 1

user stack management in multithreaded system.

Posted: Fri May 14, 2004 1:55 am
by virusx
hi,
I am working on multithreaded system. There is no problem in the kernel stack of the thread. What is the best way to implement user stack.
Each thread has its own stack. If i allocate each page for the stack. how do i detect stack overflow. I saw somewhere to place a marker at the end of the stack. But i need to check every time i access the stack.
Another way is to make address below read only or do not map the page. But how to do effectively when i have hundred threads.

Thanks.

Re:user stack management in multithreaded system.

Posted: Fri May 14, 2004 3:03 am
by gcukm
is it any different from process stack handling ?
in theory, threads represent different program counters,
within the same task
a thread stack overflow should not bother other processes,
it is internal to the current one
what is the max number of threads in your system ?
of processes ?
should there be a max number ?
perhaps the memory pointer resulting in overflow exception
had better be cast into a variable of less bits than usual;
so that in case of overflow it would initialise to zero,
rather than go off limits

Re:user stack management in multithreaded system.

Posted: Fri May 14, 2004 3:25 pm
by Ozguxxx
Well I currently dont have any protection against user stack underflows :) but I can tell that guard pages is the best way to handle user stack exceptions. Guard pages are like waste of one page in user address space but its just a page in whole 1 Gig assuming user has 1 gig of address space. Since all users have separate address spaces it does not really matter if you have 100 or 10000 threads apart from your kernel's point of view. They all lack only 1 page in their address spaces.

Re:user stack management in multithreaded system.

Posted: Mon May 17, 2004 1:45 am
by Pype.Clicker
For user stacks, you have the opportunity of using alloc-on-demand: your user program will simply attempt to expand and the kernel will give them requested pages until they attempt to expand to a "guardian" page.

So checks needn't to be performed at each operation(push/pop) but instead at each operation *on a new page*.

Re:user stack management in multithreaded system.

Posted: Mon May 17, 2004 2:33 am
by virusx
hi,
I use process to encapsulate threads. Process has address space 3.5 g. suppose i have 100 threads and each threads has its own user and kernel stack. how do i allocate stacks for all of them.

thanks

Re:user stack management in multithreaded system.

Posted: Mon May 17, 2004 3:14 am
by Pype.Clicker
solution #1: you require your user to malloc() space for each stack. This is how posix threads basically work on Linux. And yes, it means the programmer needs to 'guess' the required stack space of the thread before the thread starts ...

solution #2: use ASM programs and segmented approach. give each thread a dedicated stack segment. On stack fault, lookup for a larger vaddr region and move the stack there (copying page table entries and changing the descriptor's base is enough).
However, C programming requires stack.base == data.base

solution #3: use some other technique of expansible stacks segments. There's an article that describes how this is achievable on SPARC processors, and there's a way to do it on x86 processors aswell, but i haven't got the time to write down how so far ...

Re:user stack management in multithreaded system.

Posted: Wed May 19, 2004 6:15 am
by Xardfir
Greetings,
If your thread' is going to be "heavy" with unknown memory requirements- it should be "forked" out to it's own process.

Most threads are 'light' and can allocated space within the user's data segment by the application
either as Threadstack1[4096]
Threadstack2[4096] etc.
or malloc'd like linux on the users data section.
Note on the *DATA* section. I've seen some code that attempts to allocate memory on the *STACK* for threads and errr....... not pretty code.

Thread setting up is then as easy as creating an entry on you process table that is a duplicate of the parent's, but pointing to the function and the stack pointing correctly to the threads stack. As far as the scheduler is concerned, it's running another process that looks remarkable like the parent process.
e.g. THD1ID = CreateThread(&ThreadFunction1, &Threadstack1);
The Thread ID returned can be used in the normal way for Wait(THS1ID) or KillThread(THD1ID).
When the parent process dies, each thread can be forciibly shut down, or signalled to shut down nicely. The address space of the application isn't freed until the last thread has been closed.
This can be used for data recovery in the event that the main application has died.

Either way it is up to the programmer to allocate the necessary stack space for their threads. ergo Threads within an OS are subject to the same design rules as user threads. A file server should be a process not a thread because the process has unknown stack requirements compared to the known stack requirements of say a 'file reader thread' that works on known stack requirements ie the amount of information to be read.

To me adding guard pages at either end of a stack is overkill.
If a thread trashes it's stack - the application dies. This thread would make a good candidate for a new process.

I support Ozgunh82's suggested approach.A guard page set at the top of the user data segment provides adequate normal data/stack crash protection.

Hope this provokes happy brain swirling.

Re:user stack management in multithreaded system.

Posted: Fri May 21, 2004 2:20 am
by virusx
thanks for all of you support,
I decided to do similar to posix threads ie giver the user chance to allocate the stack using the attribute during the threadcreation. If attribute is NULL allocate default 4k.
dont bother about stack under flow and overflow. It is the user's responsibility.

And for kernel stack, I decided to use 1 page(4k). I think it will be enough.

thanks

Re:user stack management in multithreaded system.

Posted: Sat May 22, 2004 2:09 am
by Pype.Clicker
virusx wrote: And for kernel stack, I decided to use 1 page(4k). I think it will be enough.
Imho, only one page may be a bit short, especially if you have a monolithic kernel approach (and thus that the kernel has heavier tasks to perform, requiring deeper stacks)

Keep in mind that kernel stack overflow are likely to either trash kernel data or lead to system reset ...

Re:user stack management in multithreaded system.

Posted: Sat May 22, 2004 11:09 am
by quaak
We are using here 2kb for kernel stack.
;D

Re:user stack management in multithreaded system.

Posted: Sat May 22, 2004 10:02 pm
by virusx
hi,
In mine, 4k should be enough, It is a microkernel and even drivers are outside the kernel.