C言語でコルーチン(co-routine)(3)
Posted by arms22 on 2008年04月11日

C言語でコルーチンを実装してみる、その3。
前回でローカル変数の問題、状態を制御できない問題は解決した。今回はコルーチンで値を返す処理を追加した。例によって、まずはサンプルコードから。
int num_gen(coroutine_t coro)実行結果は次の通り。
{
co_begin_rettype(coro,int);
co_local_valiables{
int number;
};
co_local.number = 0;
while(1){
co_yield_ret(co_local.number++);
}
co_end;
}
int main(int argc, char *argv[])
{
coroutine_t gen1;
coroutine_t gen2;
int stack1[128];
int stack2[128];
int i;
gen1 = co_create(num_gen,0,stack1,sizeof(stack1));
gen2 = co_create(num_gen,0,stack2,sizeof(stack2));
for(i=0;i<10;i++){
co_call(gen1);
co_call(gen2);
printf("gen1 result %d,gen2 result %d\n",
co_get_retval(gen1,int),
co_get_retval(gen2,int));
}
}
% a.exenum_gen関数はint型の値を、呼び出し毎に1ずつ増やして返す関数だ。今回追加したマクロはco_begin_rettype,co_yield_ret,co_get_retvalだ。順番に見ていこう。
gen1 result 0,gen2 result 0
gen1 result 1,gen2 result 1
gen1 result 2,gen2 result 2
gen1 result 3,gen2 result 3
gen1 result 4,gen2 result 4
gen1 result 5,gen2 result 5
gen1 result 6,gen2 result 6
gen1 result 7,gen2 result 7
gen1 result 8,gen2 result 8
gen1 result 9,gen2 result 9
- co_begin_rettype(coro,int);
コルーチンの開始と戻り値の型を決める。戻り値のサイズ分、スタックに空きを作る。 - co_yield_ret(co_local.number++);
スタックに戻り値を積んで、処理を中断し呼び出しもとに戻る。 - co_get_retval(gen1,int)
コルーチンの戻り値を型を指定して取り出す。
#define co_begin_rettype(coro,type) \ローカル変数で使うスタックのアライメントを4バイトに調節している。
type *__return_addr = (type*)((coro)+1); \
co_stack_t __stack_addr = (co_stack_t)(((int)(__return_addr+1)+3)&~3); \
switch((coro)->resume){ \
case CO_INITIALALIZE:;
#define co_yield_ret(value) \
do{ \
*__return_addr=value; \
return(__LINE__); \
case __LINE__:; \
}while(0)
#define co_get_retval(coro,type) \
(*((type*)((coro)+1)))
Ads by Google
0 Comments
Leave a reply
該当の記事は見つかりませんでした。