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