Tina is a teeny tiny, header only, coroutine and fiber library!
Coroutines are little lightweight userspace threading primitives, and they are super handy. OS threads are great if you want to use multiple CPUs, but syncronizing them is tricky and cumbersome. If you just want to run more than one bit of code at a time, coroutines are much easier to use. This makes them great for lightweight uses like implementing state machines directly as easy to read code, running a script in a video game to control a cutscene, or amortizing the cost of an long algorithm over time. Unlike OS threads, having thousands or millions of coroutines is not a problem. You are really only limited by RAM.
yield()for assymetric coroutines
Tina Jobs is a simple fiber based job system built on top of Tina. (Based on the ideas here: https://gdcvault.com/play/1022186/Parallelizing-the-Naughty-Dog-Engine)
Functions are a simple and useful concept in structured programming. You give them some data, they process it, and return some data back to their caller. Coroutines on the other hand yield instead of returning, and can be resumed so they continue right where they left off.
There is a lot of confusing terminology around threading. So here's my best attempt at clarifying some of it.
So what's the difference between coroutines, fibers, generators, continuations, contexts, etc? Well... not much, and also a lot depending on who you talk to. Many aren't rigorously defined, so they tend to be used interchangeably. Some implementations operate at a language level by saving local variables. Some work by saving CPU registers. Some implementations have their own stack, while others work only within a single stack frame. Some implementations are asymmetric and can only yield back to the coroutine that resumed them, while others are symmetric and can switch to any other coroutine arbitrarily. Sometimes the terminology is simply a matter of what it's used for. For example generators are basically coroutines used like iterators.
Tina's coroutines (or fibers, or whatever you want to call them) each have their own stack, and they work by using ABI specific assembly code to save and restore the CPU registers. They can also be used in either a symmetric or asymmetric fashion which is handy. There are other coroutine/fiber libraries that provide a fast assembly implementation of course,
but as far as I know Tina is the only one with a simple header only implementation (1). I'm not always a huge fan of header only libs, but avoiding a mess of assembler files in a cross platform project is quite nice! By supporting a few of the most common ABIs, Tina should run on all of the current desktop, mobile, and console platforms available in 2021. \o/
(1) Here's a new library that is very similar to Tina: https://awesomeopensource.com/project/edubart/minicoro