Hello,
Could you explain about the intend behind platform_execute in usb_drv? I see it is similar to executing a function but it uses stack allocated by dde_kit_simple_malloc, and I don't understand why.
Always thanks for the kind explanation, Jaeyong
Hello Jaeyong,
On 01/08/2013 03:26 AM, jaeyong yoo wrote:
Hello,
Could you explain about the intend behind platform_execute in usb_drv? I see it is similar to executing a function but it uses stack allocated by dde_kit_simple_malloc, and I don't understand why.
This function is used to switch the stack and execute a given function. Since stack switching has to be performed in assembly, the function must be implemented for each platform (e.g. ARM, x86). In the great picture this is part of a very simple user-threading implementation. Each "pseudo" thread needs a stack to need lose its call trace, such a thread is scheduled using setjmp/longjmp calls (see: dde_linux/src/drivers/usb/routine.h).
Regards,
Sebastian
Please forgive my ignorance.
This function is used to switch the stack and execute a given function.
Why do we have to switch the stack? For instance, what would happen if we do not switch the stack?
Regards, Jaeyong
On Tue, Jan 8, 2013 at 7:31 PM, Sebastian Sumpf < Sebastian.Sumpf@...1...> wrote:
Hello Jaeyong,
On 01/08/2013 03:26 AM, jaeyong yoo wrote:
Hello,
Could you explain about the intend behind platform_execute in usb_drv? I see it is similar to executing a function but it uses stack allocated by dde_kit_simple_malloc, and I don't understand why.
This function is used to switch the stack and execute a given function. Since stack switching has to be performed in assembly, the function must be implemented for each platform (e.g. ARM, x86). In the great picture this is part of a very simple user-threading implementation. Each "pseudo" thread needs a stack to need lose its call trace, such a thread is scheduled using setjmp/longjmp calls (see: dde_linux/src/drivers/usb/routine.h).
Regards,
Sebastian
-- Sebastian Sumpf 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 SQL Server Development, Administration, T-SQL, SSAS, SSIS, SSRS and more. Get SQL Server skills now (including 2012) with LearnDevNow - 200+ 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_122512 _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hello Jaeyong,
This function is used to switch the stack and execute a given function.
Why do we have to switch the stack? For instance, what would happen if we do not switch the stack?
in contrast to normal function calls, user-level threads are executed without the need to return from a function. For example, let us assume that a user-level thread executes the following code:
void thread_entry() { int signal_count = 0; for (;;) { wait_for_signal(); signal_count++; printf("signal_count is %d", signal_count); ... } }
Here, the variable 'signal_count' is allocated on the thread's stack because it is a local variable. The function 'wait_for_signal()' blocks the user-level thread for an incoming event and invokes scheduler of other user-level threads. So here, a user-level context switch might happen.
Now, imagine that you have two of such threads running. Let's call them A and B. If they would share one stack, and the threads were scheduled in the order A, then B, the resulting stack would look as follows:
------------------------------------------ <- stack top context of B (i.e., 'signal_count' of B) ------------------------------------------ context of A (i.e., 'signal_count' of A) ------------------------------------------
How would the stack look after the user-level scheduler would now pick A? If we just switched to the last stack pointer used by A, the picture would look like this:
------------------------------------------ context of B (i.e., 'signal_count' of B) ------------------------------------------ <- stack top context of A (i.e., 'signal_count' of A) ------------------------------------------
Now, thread A executes the 'printf' function, which uses the stack and thereby overwrites the context of 'B'. After returning from 'printf', the stack would look like this:
------------------------------------------ left-overs of the printf function ------------------------------------------ <- stack top context of A (i.e., 'signal_count' of A) ------------------------------------------
The context of B has been overwritten by the function call frames used by the 'printf' function and its subroutines.
By hosting the stack of each user-level thread in a distinct memory area, such situations cannot happen. The threads can be executed in any order without overwriting each other's context.
Cheers Norman
It enlightened me. Thanks a lot!
Jaeyong
On Wed, Jan 9, 2013 at 7:46 PM, Norman Feske <norman.feske@...1...>wrote:
Hello Jaeyong,
This function is used to switch the stack and execute a given function.
Why do we have to switch the stack? For instance, what would happen if we do not switch the stack?
in contrast to normal function calls, user-level threads are executed without the need to return from a function. For example, let us assume that a user-level thread executes the following code:
void thread_entry() { int signal_count = 0; for (;;) { wait_for_signal(); signal_count++; printf("signal_count is %d", signal_count); ... } }
Here, the variable 'signal_count' is allocated on the thread's stack because it is a local variable. The function 'wait_for_signal()' blocks the user-level thread for an incoming event and invokes scheduler of other user-level threads. So here, a user-level context switch might happen.
Now, imagine that you have two of such threads running. Let's call them A and B. If they would share one stack, and the threads were scheduled in the order A, then B, the resulting stack would look as follows:
------------------------------------------ <- stack top context of B (i.e., 'signal_count' of B)
context of A (i.e., 'signal_count' of A)
How would the stack look after the user-level scheduler would now pick A? If we just switched to the last stack pointer used by A, the picture would look like this:
context of B (i.e., 'signal_count' of B) ------------------------------------------ <- stack top context of A (i.e., 'signal_count' of A)
Now, thread A executes the 'printf' function, which uses the stack and thereby overwrites the context of 'B'. After returning from 'printf', the stack would look like this:
left-overs of the printf function ------------------------------------------ <- stack top context of A (i.e., 'signal_count' of A)
The context of B has been overwritten by the function call frames used by the 'printf' function and its subroutines.
By hosting the stack of each user-level thread in a distinct memory area, such situations cannot happen. The threads can be executed in any order without overwriting each other's context.
Cheers 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 Java SE, Java EE, Eclipse, Spring, Hibernate, JavaScript, jQuery and much more. Keep your Java skills current with LearnJavaNow - 200+ hours of step-by-step video tutorials by Java experts. SALE $49.99 this month only -- learn more at: http://p.sf.net/sfu/learnmore_122612 _______________________________________________ Genode-main mailing list Genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main