Live data from Hacker News

Implementing simple cooperative threads in C

brennan.io

1–10 of 88 posts

Re: Implementing simple cooperative threads in C

#2
> It’s like a goto statement, but it can even be used to jump outside of a function. It’s also a lot more difficult to read than a goto, since it looks like a regular function call.

Ah! Blood pressure rising!

> Like with goto, the common advice is to avoid

Whew. And then goes on to make a really good case for complicated task perform with simple error handling.

It’s a good application for not exactly general use cooperative routines but a specific use case of performing multiple procedural steps.

I think there it falls short and where an RTOS/OS will be more useful is when you have to wait on one of those steps.

I think that’s the harder example with the example of an HTTP request is waiting for the response and keeping that context ready and blocking in a separate thread. That ends up being easy to read and maintainable. But I suppose there is no reason you can’t do both.

Re: Implementing simple cooperative threads in C

#4

> It’s like a goto statement, but it can even be used to jump outside of a function. It’s also a lot more difficult to read than a goto, since it looks like a regular function call. Ah! Blood pressure rising! > Like with goto, the common advice is to avoid Whew. And then goes on to make a really good case for complicated task perform with simple error handling. It’s a good application for not exactly general use coop…

Does your blood pressure also rise from use of exceptions?

Because the pattern that emerges with setjmp/longjmp is pretty similar, and that's the most common use: to simulate what other languages offer with exceptions. The most prominent libraries I can think of that force you to do this are image related, libpng and libjpeg both use longjmp to handle errors [though IIRC it's optional in the latter].

Re: Implementing simple cooperative threads in C

#5

A more common method of implementing this that avoids setjmp and longjmp is to code a little assembly to do the stack switch. This is typically faster and easier to port, see: https://probablydance.com/2013/02/20/handmade-coroutines-for...

Faster I can believe, but how can custom asm be more portable than setjmp/longjmp which are standard since C89?

Although in this particular instance TFA also uses inline assembly to setup the stack, so it's moot.

Re: Implementing simple cooperative threads in C

#6
post #5

A more common method of implementing this that avoids setjmp and longjmp is to code a little assembly to do the stack switch. This is typically faster and easier to port, see: https://probablydance.com/2013/02/20/handmade-coroutines-for...

Faster I can believe, but how can custom asm be more portable than setjmp/longjmp which are standard since C89? Although in this particular instance TFA also uses inline assembly to setup the stack, so it's moot.

I'm wrong, I seemed to remember many platforms not supporting them but a quick Google search reveals its just a foggy memory. I was probably thinking about ucontext actually.

Re: Implementing simple cooperative threads in C

#7
Interesting to compare and contrast with Simon Tatham's method of implementing Co-Routines in C:

https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

Submitted here: https://news.ycombinator.com/item?id=23293835

That's decades old, and actually used in PuTTY.

Re: Implementing simple cooperative threads in C

#9
FWIW, the original implementation of Java (when it was known as Oak) used this trick to manage user level threading. There was also a some code to do the stack swap since you were in a virtual machine anyway, that stuff was all there to be adjusted.

Random meta note brenns10, the idiom for giving up the processor is 'yield' (rather than 'relinquish') it is common in cooperative systems.

That said, the code in Java that switched threads was called the 'trampoline' code since you bounced in, switched threads and bounced out.

And my last comment is that if you set up your scheduler in a way that it has a 'runnable' and 'sleeping' queue, you can do clever things like have a task sleep on a mutex or other conditional variable and wake up when that variable does what you're waiting for. It makes implementing network services that service multiple clients much cleaner.

Re: Implementing simple cooperative threads in C

#10

Interesting to compare and contrast with Simon Tatham's method of implementing Co-Routines in C: https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html Submitted here: https://news.ycombinator.com/item?id=23293835 That's decades old, and actually used in PuTTY.

That's really cool, and much lighter weight for the purpose of coroutines!
Post reply on HN