https://github.com/dearblue/micro-co
pseudo coroutine library with switch and label-as-value
https://github.com/dearblue/micro-co
coroutines
Last synced: 2 months ago
JSON representation
pseudo coroutine library with switch and label-as-value
- Host: GitHub
- URL: https://github.com/dearblue/micro-co
- Owner: dearblue
- License: other
- Created: 2018-01-21T10:12:21.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2018-02-18T13:55:09.000Z (over 7 years ago)
- Last Synced: 2025-02-12T11:35:10.268Z (4 months ago)
- Topics: coroutines
- Language: C
- Homepage:
- Size: 8.79 KB
- Stars: 0
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# micro-co - 低機能で簡易な疑似コルーチンの実装
``switch`` 文のみで実装した疑似コルーチンです。
gcc (あるいは互換コンパイラ) の "label as value" が利用できるならば切り替えることが可能です。
## 特徴
* (たぶん) 環境・コンパイラを選ばないで利用出来ます。
* 引数や戻り値に制限がありません。
* ``co_yield()`` は、入れ喰い状態になった深いブロックや ``if`` ``for`` ``while`` ``do-while`` に記述できます。
* 省メモリ。
* C++ でも (一応) 動作します。
* 一つの関数の中で複数の ``co_begin() ... co_end()`` を入れ子にすることが出来ます
(入れ子になった ``co_begin()`` の手前に ``co_checkpoint()`` が必要です)。### 制限
* スケジューラはありません。全部手書きで行います。
* ``co_XXX()`` を使っている関数のスタック変数は ``co_yield()`` する度に失われます。
* ``co_begin()`` 〜〜〜 ``co_end()`` の中で呼び出した子関数からは ``co_yield()`` 出来ません。
その場合は ``co_begin()`` 〜〜〜 ``co_end()`` を入れ子にして下さい。
* ``co_begin()`` と ``co_end()`` はネストを合わせる必要があります。
* ``co_begin()``、``co_yield()``、``co_end()`` を単一行に記述することは出来ません。
必ず複数行に分割して記述する必要があります。
* ``co_begin()`` 〜〜〜 ``co_end()`` の中で、``switch`` 文の中に ``co_yield()`` を含めることは出来ません。
一つの ``co_yield()`` の中で完結した ``switch`` 文に限定されます。
* 問題のない書き方:
```c
co_begin(s);
...co_yield(0);
switch (...) {
case ...:
...;
case ...:
/* 入れ子にした co_begin() ... co_end() を置くことは可能 */
...;
}co_yield(1);
...co_end();
```* ***問題のある***書き方:
```c
co_begin(s);
...switch (...) {
case ...:
co_yield(0);
...;
case ...:
co_yield(1);
...;
}co_end();
```## 簡易リファレンス
* ``co_state_t context = CO_INIT;``
疑似コルーチンのコンテキストを宣言し初期化する。
* ``void co_begin(co_state_t *co)``
疑似コルーチンの開始を宣言する。
* ``void co_yield(RET)``
処理を疑似コルーチンから呼び出し元に戻す。その時の戻り値は RET となる。
再び関数が呼ばれた場合、この直後からの再開となる。
* ``void co_checkpoint(void)``
処理の再開位置を保存する。
``co_yield`` や ``co_halt`` 以外で関数を抜けた場合でも、この直後からの再開となる。
* ``void co_end(void)``
疑似コルーチンの終了を宣言する。
処理はそのまま続行される。
次回以降は、関数が呼ばれてもこの直後からの再開となる。
* ``void co_halt(RET)``
``co_end`` に似ているが、処理を打ち切り常に RET を返すようになる。
何度関数が呼ばれても RET を返すだけとなる。## 調整
* 定義名 ``MICRO_CO_USE_SWITCH``
コンパイラに ``MICRO_CO_USE_SWITCH`` を定義するように指定すると、内部実装を ``switch`` に切り替えます。
gcc (あるいは互換コンパイラ) の "label as value" が利用できない環境では、常に ``MICRO_CO_USE_SWITCH`` が定義された状態となります。
```
$ gcc -DMICRO_CO_USE_SWITCH ....
```* 定義名 ``MICRO_CO_FORCE_USE_LABEL_AS_VALUE``
gcc (あるいは互換コンパイラ) の "label as value" の利用を強制します。
``MICRO_CO_USE_SWITCH`` を打ち消すため、可能な限り利用しないで下さい。
## Specification
* Product name: micro-co
* Product quality: PROTOTYPE
* Author: [dearblue](https://github.com/dearblue)
* Project page:
* Licensing: [Creative Commons Zero License (CC0 / Public Domain)](LICENSE)