Coroutines are a control-flow primitive which allows for a lot of useful things, including advancing program state while a coroutine waits on a syscall, generators, iterators, producer-consumer patterns with channels, and combinations of these things. They generalize function calls, or structure goto, if you prefer.
Some of these applications are glossed as concurrent, particularly their use to free the thread when execution blocks, but all of them are single-threaded. Goroutines are preëmptively scheduled, and can be relocated between threads transparently. That isn't really a coroutine, which is why they have a different name.
The README has some notes on how to use Neco coroutines in a multithreaded environment. It's basically how you'd run execution paths of multiple function calls on several threads, because coroutines are an orthogonal concern to threads.
your library looks well written and clean. thanks for sharing.
if anyone else wants to go coroutine spelunking, these were interesting to me:
https://github.com/higan-emu/libco/tree/master
https://github.com/Tencent/libco
https://github.com/hnes/libaco
https://kernel.googlesource.com/pub/scm/virt/kvm/qemu-kvm/+/...
https://tia.mat.br/posts/2012/09/29/asynchronous_i_o_in_c_wi...
https://www.cs.uml.edu/~bill/cs516/context_paper_rse-pmt.pdf
Handling multiple threads to access multiple CPUs would make it far more complex. And frankly a single thread is plenty for handling, say, a chat server.