Hello, Uwe

>> *
>> * A thread may be associated with more than one stack. Additional secondary
>> * stacks can be associated with a thread, and used for user level scheduling.
> Did you see this ^ ? {g,s}etcontext() count as user level scheduling!

yes, - but probaby we have a different understanding of this term.
If we have 2 os threads, running in the user space, - I assume that I can run 
code in 1 thread and then switch this running code to another thread (second in 
this example ) and continue execution? like call makecontxt/getcontex from 
first OS thread and call setcontext with taken data in second OS thread?
I do not pretend for anything related to OS/etc, including invocation of them - 
I just want to be able to continue execution in already started os.

Current golang code support this model in goroutines, and the only problem that 
it use small number of thread local storage (TLS) variables for operations.
I found that if I switch code in the same way as I does in, e.g. Linux, - then 
in genode it does not work because linux define «myself» using sys calls to 
obtain threadid (this operation is stack agnostic), while genode hardwire stack 
to backbend OS thread and do not allow simple setcontext() like switch to 
another OS (non-user!) thread with own stack, and, therefore, TLS variables 
became wrong.

>> 
>> So, to fix it I need during switch of context to non-local thread 
>> (setcontext() or even longjump() functions) I should update these data to 
>> current running stack.
> user level switching is only valid within the same thread. The only way to do 
> this is to do a local
> user level switch to a user level thread that immediately blocks the os level 
> thread and wakes the os level
> thread, that is blocked in the same procedure and corresponds to the target 
> user level thread. At wakeup that
> user level thread, which was blocked at the os level, reads the target user 
> level thread and makes a local
> user level switch to it.
> The Mutex on which the user level threads blocks (at least its address) needs 
> to be part of the context.

thank you for proposed solution. 
I have a question related to it:  you assume to start the same function with 
stack instance or different one?
 if the same - it will contain correct user state, but incorrect (old) os 
thread related data (as I have now);
if not the same - I need to read the content of old stack/etc, parse it and 
copy to new stack on new OS thread? 

later example is incorrect: if we have a local reference stored inside stack, 
then we doomed… 

this is example of code which will not works:

f(int * p)
{
        *p = 2;
        getcontext()
        … here we can appear in old or new threads
        *p = 3; // here we will point to variable in local stack - should be 
sure that it is not outside
}

g()
{
        int a=0;
        f(&a);
        print(a);
}

if I call g() and switch inside f() to new thread - then local stack of g() and 
f() will contain reference &a to variable inside the stack. So, if I just copy 
stack, run new code and free old stack - it will contain a reference to old 
stack and "3" will be written not to a variable but to somewhere else.

In golang code typically we first save context in arbitrary os thread using 
getcontext(), then we will run code which just read saved context and set it 
for current OS thread.
if this is the same OS thread - everything works ok. IF this is another OS 
thread - we already appears in it and try to just setup RSP register in x86 to 
point to old stack which attributed with the old OS thread (reference to Thread 
object and UTCB at least in genode)…

I suppose that the only reasonable straightforward  solution here is to copy os 
thread data (Thread and utcb objects) from new thread where I appears to stack 
to be setup (taken typically from getcontext/makecontext call). May be by 
introducing of re_construction function (or method?) to be applied to Stack 
instance. it definitely contains reference to itself (eg _thread and _utcb 
pointers) and simple memcpy will not works… main question here is that this 
approach do require confidence that Thread and UTCB objects do not contains 
references to fields inside - and for UTCB this is definitely not low level OS 
agnostic...

More generic solution: could be  implementation of kind of registry for 
associations between OS level thread and genode Thread without stack instances, 
potentially kind of virtualisation of low lever OS thread id with 1 to 1 
translation to genode id. 
IMHO in general genode good to have virtualisation  like namespaces/cgroups in 
linux or windows. this also simplify checkpoint/restore, migration, fast 
restart of drivers and core and other related cross-instances operations.

Alexander



_______________________________________________
Genode users mailing list
[email protected]
https://lists.genode.org/listinfo/users

Reply via email to