
Show HN: Minimal Fibers - bgongfu
https://github.com/basic-gongfu/cixl/blob/master/devlog/minimal_fibers.md
======
dfbrown
Worth noting that ucontext is quite slow (at least on linux):
[https://www.boost.org/doc/libs/1_67_0/libs/context/doc/html/...](https://www.boost.org/doc/libs/1_67_0/libs/context/doc/html/context/performance.html)

~~~
bgongfu
It's slower than Boost Context for sure, but still around 10x faster than
(ab)using Pthreads on Linux. Until someone releases a faster standalone C
library it's still the fastest portable solution for projects like Cixl that
can't afford dragging C++ around.

~~~
manwe150
There's already many fast, portable, standalone C libraries for this. For
instance, see table 1 of [https://www.gnu.org/software/pth/rse-
pmt.ps](https://www.gnu.org/software/pth/rse-pmt.ps). The assembly code for a
context switch is pretty minimal (on most platforms, it's just setjmp and
longjmp) if you don't try manage the signal state. I would be surprised if
there was significant variance in performance (other than whether it chooses
to switch the signal mask). Additionally, many language runtimes directly
support it without any extra effort on your part. So if you choose to instead
use one of those language, you get a fast portable solution without needing to
do any extra work to pick a support library (for example, D-Lang LDC, PyPy,
Go, Julia).

~~~
spc476
I implemented coroutines for C with assembly [1] (x86 32 and 64 bit). I took
advantage of the calling convention to cut down on the amount of state to save
(4 registers for x86 32b and six for x86 64b). Mixing this with signals is
probably unwise [2]. So far I've tested the code on Linux and Mac OS-X and it
works (although I might not use it for C++ either).

[1]
[https://github.com/spc476/C-Coroutines](https://github.com/spc476/C-Coroutines)

[2] In my not-so humble opinion, using signals _at all_ is not wise.

~~~
gpderetta
The shortest contest switch sequence I could come up on x86-64 is three
instructions:

    
    
      xchg  %rsp, %rdx
      leaq  1f(%rip), %rax
      jmp   *%rsi

1:

It it expect the target stack ptr/ip pair to be in rdx/rsi and saves the
current stack ptr and ip in rdx/rax. It does not save any register and uses
gcc asm clobbers to instruct the compiler to save any other register.

Code at [1]. The comments about hacks and ub is because I'm trying to
transparently propagate exceptions across coroutines, otherwise the stack
switching us fairly robust (although GCC specific).

[1]
[https://github.com/gpderetta/delimited/blob/master/delimited...](https://github.com/gpderetta/delimited/blob/master/delimited.hpp)

------
backpropaganda
Slightly OT, but do people know of any good small language which compiles to
C? I'm not looking for big languages like C++, Nim, or Rust, but something
which is essentially just C, but with some minimal modernization, such as
perhaps being able to import modules, and doing away with header files.

~~~
steveklabnik
I think you want Zig!

~~~
backpropaganda
Zig looks amazing! Thank you! While it doesn't compile to C, you read my mind
that I actually wanted a C replacement rather than compile to C.

~~~
steveklabnik
Great! Yeah, that's what I was guessing, glad that I guessed correctly.

