Hi Juan, On 06/12/2018 12:27 PM, Juan Ignacio Carrano wrote: > The current RIOT scheduler will only switch between threads with the > same priority if there is an explicit yield, or if there occurs a > preemption by a higher priority thread.
RIOT's scheduler used to work like that: any preemption by a higher priority thread would advance the current priority's circular runqueue. That has been fixed years ago. Nowadays, only if a thread calls explicit thread_yield() or it blocks, it's "friends" will be scheduled. > Coroutines make it possible to program asynchronous code in a > blocking style - see "await". This is more natural and easier that > using callbacks. How does it compare to sending / receiving messages? > This is almost cooperative multithreading (within the same "priority > group"), except there is no guarantee that after a thread in a group is > preempted, it will be that thread an not another with the same priority > that will get resumed. Maybe that is the current behavior, but I'm > having some trouble understanding the scheduler code. It *should* be current behaviour, but I'm sure there are both platforms and modules that call "thread_yield()" instead of "thread_yield_higher()". >> Assigning the same priority to two or more threads is usually not a >> good idea. Can't really argue with that, can you? ;) More seriously, that note can definitely be improved. > A good starting point would be to guarantee threads with the same > priority get cooperatively scheduled 100% of the time. This means that > if one thread is preempted by a higher priority task, then no other > thread but that one will get resumed. In other words, the only way to > switch between threads with the same priority is explicitly yielding > from one. As said, that guarantee *should* be in place, if calling a blocking function can be considered "yielding". We might consider to make even blocking of a thread not advance that thread priority's run queue, but I'd be reluctant to change the semantics that much. > Coroutines / Fibers do not have to be full fledged threads. The TCB can > be simpler and some objects can be shared with other fibers. I count 12 bytes minimum for the TCB on 32bit architectures. There's not much more that can be shaved off, and it would not have significant impact, as already the stack space necessary for a thread's registers when storing the context, apart from a stack itself, is the largest part of a thread's overhead. > See the PR > on a thread-safe implementation of newlib > (https://github.com/RIOT-OS/RIOT/pull/8619) for an idea of the overhead > that thread-safety imposes. This is not the overhead of thread-safety per se, but of the C library functions that were designed to save state in global variables, when there was no multi-threading. There are thread-safe alternatives to each one of them in the C library, which do not impose the overhead. Kaspar _______________________________________________ devel mailing list devel@riot-os.org https://lists.riot-os.org/mailman/listinfo/devel