Skip to content

Commit

Permalink
Small docs update
Browse files Browse the repository at this point in the history
  • Loading branch information
tylov committed Jan 7, 2025
1 parent 9599ea7 commit 85877a3
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ high-level generic datatypes, iterators and algorithms, and through a consistent
object ownership and lifetimes.

<details>
<summary><b>The big picture: Why we need a modern generic library for C</b></summary>
<summary><b>Reasons why you may want to you use STC</b></summary>
C is still among the most popular programming languages, despite the fact that it was created
as early as in 1972. It is a manifestation of how well the language was designed for its time,
and still is. However, times are rapidly changing, and C among others is starting to lag
Expand All @@ -20,8 +20,8 @@ the standard library, but also when it comes to safety and vulnerabilities. Both
are addressed with the STC library.

#### A. Missing features in the C standard library, which STC provides
* Large set of high performance, generic/templated typesafe container types, including smart pointers and bitsets.
* String type with utf8 support and short string optimization (sso), and two string-view types.
* A wide set of high performance, generic/templated typesafe container types, including smart pointers and bitsets.
* String type with utf8 support and short string optimization (sso), plus two string-view types.
* Typesafe and ergonomic **sum type** implementation, aka. tagged union or variant.
* Flexible **coroutine** implementation with excellent ergonomics, error recovery and cleanup support.
* Fast, modern **regular expressions** with full utf8 and a subset of unicode character classes support.
Expand Down
25 changes: 17 additions & 8 deletions docs/coroutine_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,23 @@

This is small and portable implementation of coroutines.

* Stackful, typesafe coroutines. Allows both asymmetric coroutine calls and symmetric transfer of control.
* Great ergonomics and minimal boilerplate code. No awkward macros.
* Tiny memory usage, very efficient context switching, and no allocation required by default.
* Coroutines are to be cleaned up at the `cco_finally:` label. Will also happen on errors and cancelation.
* Allows "throwing" errors. To be handled in a `cco_finally:` during the immediate unwinding of the call stack.
* Stackful or stackless typesafe coroutines.
* Supports both asymmetric coroutine calls (structured concurrency) and symmetric transfer of control.
* Good ergonomics and minimal boilerplate code.
* Supports "throwing" errors, handled in `cco_finally` during immediate unwinding of the call stack.
* Recovery from errors mechanism.
* Small memory usage and efficient context switching. No heap allocation required by default.
* Coroutines may be cleaned up at the `cco_finally` label. Will also happen on errors and cancelation.
Unhandled errors will exit program with an error message including the offendig throw's line number.

Because these coroutines are stackful, all variables used within the coroutine scope (where usage crosses `cco_yield..` or `cco_await..`) must be stored in a struct which is passed as pointer to the coroutine. This has the advantages that they become extremely lightweight and therefore useful on severely memory constrained systems like small microcontrollers where other solutions are impractical.
STC coroutines may behave stackless or stackful.
- In stackless mode, the root coroutine object stores the call tree of coroutine objects (typically
on the stack), which holds all variables used within their coroutine scopes. This has the advantages
that they become extremely lightweight and therefore useful on severely memory constrained systems
like microcontrollers with limited resources.
- In stackful mode, the coroutine frames are allocated on the heap just before they await another
coroutine. Examples below.


## Methods and statements

Expand Down Expand Up @@ -413,7 +422,7 @@ int main(void)
```
</details>

#### Heap allocated task frames
#### Stackful coroutines allocated on the heap

Sometimes the call-tree is dynamic or more complex, then we can dynamically allocate the coroutine frames before
they are awaited. This is somewhat more general and simpler, but requires heap allocation. Note that the coroutine
Expand All @@ -422,7 +431,7 @@ the previous, but also shows how to use the env field in `cco_runtime` to return
call/await:

<details>
<summary>Implementation of heap allocated task frames</summary>
<summary>Implementation of stackful coroutines</summary>

[ [Run this code](https://godbolt.org/z/TbWYsbaaq) ]
```c++
Expand Down

0 comments on commit 85877a3

Please sign in to comment.