Skip to content

Instantly share code, notes, and snippets.

@yutopp
Created November 3, 2017 15:58
Show Gist options
  • Save yutopp/d3a184f3389df819a5b4b99f2da9b774 to your computer and use it in GitHub Desktop.
Save yutopp/d3a184f3389df819a5b4b99f2da9b774 to your computer and use it in GitHub Desktop.

参考資料

ざっと調べた。言語を実装する時に疑問に思う細かい部分はまだ拾いきれていない(探せばありそう)。

Stackless coroutine

コルーチン内で別の関数を呼び出す場合、その関数の呼び出し中に現在のコルーチンをsuspend不可とする制限をもたせる(call stackが深い部分でsuspendを許可しない)。 その制限によって、コルーチンのsuspend時に関数のcall stackを全て保存する必要がなくなる。

stackが必要なのはコルーチン実行時のみ(実行時は通常の関数と同等のため、これは必要)で、suspend時はローカル変数と次回の実行ポイント程度をコンテキストに保持しておけばよい。

そういう意味でstackless?

メリット

軽量にみえる(保持する情報が少ない)

デメリット

coroutine内で無名関数を作るようなユースケースで、その無名関数の中ではcoroutineのsuspendは出来ない。 例えば、map関数の途中でsuspend(yield)するようなコード。

coroutine内のコード生成が複雑になりそうだが…(yieldする部分でbasicblockを切ってswitchに変換するような機構で作れる。状態機械への変換) デストラクタの機構がある言語だとどうするんだろうか…

コア言語のサポートが必要にみえる。yield部分のコード生成が必要なため。

Stackful coroutine

stacklessと対象に、いかなるタイミングでcorontineをsuspendすることができる。 こちらはcall stackと実行レジスタを全てコンテキストで保持するため。

メリット

ライブラリ実装でなんとかできる。

デメリット

メモリ使用量やコンテキストスイッチが重そう(call stack保持であったりstackを切り替えるのでキャッシュとかなんかありそう)
伸長するスタックをヒープか現在のスタックに作ってそれをコンテキストとしてコルーチンを呼び出す方法が一般的?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment