← Back to team overview

kicad-developers team mailing list archive

Re: KiCad Coroutines

 

Hi Tom,

I've uploaded now a few different implementations on my personal branch:

https://code.launchpad.net/~torstenhtr/+junk/coroutines

I've tried, as I've written in my first mail, Windows Fibers and Pthreads. I've implemented a "stress test" to compare the implementations and also "stackless" coroutines. 

My impressions are so far:

Stackful coroutines:
--------------------

* It's very tricky to get stackful implementations to run stable. Any small fault results in a crash or deadlock.

* The most critical part is stack handling. For Windows Fibers / Pthreads the library does the job. There are also 
some hacks to get Setjmp()/Longjmp() working with multiple stacks, as Jean-Pauls link has shown, I've tried it but that was crashing (Setjmp()/Longjmp() seems to be broken too on MinGW64).

* Side effects / show stoppers: It's not recommened to use threads for the wxWidgets GUI, OpenGL requires a context switch per thread.

* As already known, Boost::Context is broken on Msys2 - makes it sense that such a low level library has to be maintained by KiCad developers (?)

* Is context switching always safe (side effects with 3rd party libraries / Python etc.)? 

Stackless coroutines:
---------------------

* Relative easy to handle, because based on switch()/case().
* Safer, a wrong state causes only the exit of the coroutine but not a crash.
* Simple implementation

* More verbose, you need to use macros like CR_BEGIN(..) CR_END(..)
* Syntax restrictions
* Special care of local variables is required

You can find a paper about this approach here:
http://dunkels.com/adam/dunkels06protothreads.pdf

I've used your coroutine class and have adapted it to be similar to protothreads. The actual state is stored in the instance of this class. Compare also the "stress test" example. All implementations have the same output as result of this test program.

The stackless implementation is my favorite. There are less side effects, based on the C++ standard library and the coroutines consume less resources. This outweights in my opinion the disadvantage, that the coroutine functions are more time-consuming to write.

Thanks,
Torsten

>> void my_tool()
>> {
>> wait(event1);
>> do_something();
>> wait(event2);
>> do_something_else();
>> }
>> 
>> All of the stack switching "magic" is hidden. You can find an example in
>> include/tool/examples/coroutine_example.cpp
>> 
>> 
>> Concerning boost::context, I see two options:
>> - get rid of the coroutines (i.e. rewrite all event loops/calls in the
>> GAL tools). Painful but doable, I would prefer to spend my time doing
>> something more productive (e.g. porting the remaining tools to GAL).
>> - turn boost::context into a single .cpp file library that one can
>> just add to the project and forget about it (think of ClipperLib as an
>> example).
>> 
>> As a side comment, I'm not surprised that boost devs insist on using
>> MASM under Windows - the syntax of the GNU assembler on x86/x86_64
>> platforms is just disgusting.
>> 
>> Tom


Follow ups

References