Hello,
While I was browsing source code, I found two confusing variables: At genode/base/include/base/thread.h Thread_base::Context {
long stack[];
addr_t stack_base; }
Although, they are commented a bit, it is hard to understand what are they doing and what's the difference. Could you tell me about them more?
Best, Jaeyong
Dear Jaeyong,
While I was browsing source code, I found two confusing variables: At genode/base/include/base/thread.h Thread_base::Context {
long stack[]; addr_t stack_base; }
Although, they are commented a bit, it is hard to understand what are they doing and what's the difference. Could you tell me about them more?
please let me first refer you to the brief description of the concept behind the code:
http://genode.org/documentation/release-notes/10.02#New_thread-context_manag...
Each 'Thread_base' object is accompanied by a 'Thread_base::Context' object, which holds the thread's stack and information about thread-local storage (i.e., the UTCB) and similar meta data. In contrast to 'Thread_base' objects, which are plain C++ objects that can reside anywhere (on BSS, heap, or even on a stack), thread context objects are placed within the so-called thread-context area, which is a region of the process' virtual address space managed by the process itself. Each thread owns a 1MB portion of the context area. Only a tiny bit of this portion is actually used for the thread context. The gaps between the thread contexts are not populated with memory. This way, stack overruns will result in an unresolvable page fault (similar to a segmentation fault) rather than corrupted memory.
Each thread context consists of two parts, meta data expressed by the 'Thread_base::Context' type and the stack. Whereas the meta data has the same size and layout for each thread (well, the main thread is an exception here), the stack size differs from thread to thread. The metadata is always positioned such that it starts after the stack. Because the stack always grows from higher to lower addresses, an overrunning stack won't overwrite its meta data. The 'stack_base' variable points to the "other end" of the stack - the lower one which would get crossed if the stack overruns.
I hope this description could be of help. Do you have a suggestion about a comment that would have helped you to get a better understanding in the first place? I'd like to make the situation easier for future readers of the code.
Best regards Norman
Thanks a lot! It is very clear now.
Actually, the reason that I have confused is the following: If you see the source code below, the type of stack is long [] and the type of stack_base is addr_t. Although they are both pointers, it confuses me that one is pure address (addr_t) and the other is long []. That's why I conjectured they could be different things.
Also, is there a particular reason that you position thread_base in between stack and stack base? If not, I think placing stack and stack_base right next to each other would be better (just an opinion).
/** * Top of the stack */ long stack[];
/** * Pointer to corresponding 'Thread_base' object */ Thread_base *thread_base;
/** * Virtual address of the start of the stack * * This address is pointing to the begin of the dataspace used * for backing the thread context except for the UTCB (which is * managed by the kernel). */ addr_t stack_base; Best regards, Jaeyong
On Sat, Dec 29, 2012 at 4:37 AM, Norman Feske <norman.feske@...1...>wrote:
Dear Jaeyong,
While I was browsing source code, I found two confusing variables: At genode/base/include/base/thread.h Thread_base::Context {
long stack[]; addr_t stack_base; }
Although, they are commented a bit, it is hard to understand what are
they
doing and what's the difference. Could you tell me about them more?
please let me first refer you to the brief description of the concept behind the code:
http://genode.org/documentation/release-notes/10.02#New_thread-context_manag...
Each 'Thread_base' object is accompanied by a 'Thread_base::Context' object, which holds the thread's stack and information about thread-local storage (i.e., the UTCB) and similar meta data. In contrast to 'Thread_base' objects, which are plain C++ objects that can reside anywhere (on BSS, heap, or even on a stack), thread context objects are placed within the so-called thread-context area, which is a region of the process' virtual address space managed by the process itself. Each thread owns a 1MB portion of the context area. Only a tiny bit of this portion is actually used for the thread context. The gaps between the thread contexts are not populated with memory. This way, stack overruns will result in an unresolvable page fault (similar to a segmentation fault) rather than corrupted memory.
Each thread context consists of two parts, meta data expressed by the 'Thread_base::Context' type and the stack. Whereas the meta data has the same size and layout for each thread (well, the main thread is an exception here), the stack size differs from thread to thread. The metadata is always positioned such that it starts after the stack. Because the stack always grows from higher to lower addresses, an overrunning stack won't overwrite its meta data. The 'stack_base' variable points to the "other end" of the stack - the lower one which would get crossed if the stack overruns.
I hope this description could be of help. Do you have a suggestion about a comment that would have helped you to get a better understanding in the first place? I'd like to make the situation easier for future readers of the code.
Best regards Norman
-- Dr.-Ing. Norman Feske Genode Labs
http://www.genode-labs.com · http://genode.org
Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
Master HTML5, CSS3, ASP.NET, MVC, AJAX, Knockout.js, Web API and much more. Get web development skills now with LearnDevNow - 350+ hours of step-by-step video tutorials by Microsoft MVPs and experts. SALE $99.99 this month only -- learn more at: http://p.sf.net/sfu/learnmore_122812 _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hello Jaeyong,
Also, is there a particular reason that you position thread_base in between stack and stack base? If not, I think placing stack and stack_base right next to each other would be better (just an opinion).
there is no particular reason for this sequence. It is important that 'stack' is the first member but we could make 'stack_base' the second one if this makes the code easier to swallow.
Best regards Norman