void kz_start(kz_func_t func, char *name, int priority, int stacksize, int argc, char *argv[]) { kzmem_init(); /* 動的メモリの初期化 */ /* * 以降で呼び出すスレッド関連のライブラリ関数の内部で current を * 見ている場合があるので,current を NULL に初期化しておく. */ current = NULL; memset(readyque, 0, sizeof(readyque)); memset(threads, 0, sizeof(threads)); memset(handlers, 0, sizeof(handlers)); memset(msgboxes, 0, sizeof(msgboxes)); /* 割込みハンドラの登録 */ thread_setintr(SOFTVEC_TYPE_SYSCALL, syscall_intr); /* システム・コール */ thread_setintr(SOFTVEC_TYPE_SOFTERR, softerr_intr); /* ダウン要因発生 */ /* システム・コール発行不可なので直接関数を呼び出してスレッド作成する */ current = (kz_thread *)thread_run(func, name, priority, stacksize, argc, argv); /* 最初のスレッドを起動 */ dispatch(¤t->context); /* ここには返ってこない */ }
/* 初期スレッドの起動 */ void kz_start(kz_func_t func, char *name, int priority, int stacksize, int argc, char *argv[]) { /* 動的メモリの初期化 */ kzmem_init(); /* * 以降で呼び出すスレッド関連のライブラリ関数の内部で * current を見ている場合があるので、currentをNULLに初期化しておく */ current = NULL; memset(readyque, 0, sizeof(readyque)); memset(threads, 0, sizeof(threads)); memset(handlers, 0, sizeof(handlers)); memset(msgboxes, 0, sizeof(msgboxes)); thread_setintr(SOFTVEC_TYPE_SYSCALL, syscall_intr); thread_setintr(SOFTVEC_TYPE_SOFTERR, softerr_intr); /* * システムコール発行不可なので直接関数を呼び出してスレッド作成する */ current = (kz_thread *)thread_run(func, name, priority, stacksize, argc, argv); /* * 渡されたスタックポインタをもとに実行される=上で登録したcurrentが実行される */ dispatch(¤t->context); /* ここには返ってこない */ }
static void call_functions(kz_syscall_type_t type, kz_syscall_param_t *p) { /* システム・コールの実行中にcurrentが書き換わるので注意 */ switch (type) { case KZ_SYSCALL_TYPE_RUN: /* kz_run() */ p->un.run.ret = thread_run(p->un.run.func, p->un.run.name, p->un.run.priority, p->un.run.stacksize, p->un.run.argc, p->un.run.argv); break; case KZ_SYSCALL_TYPE_EXIT: /* kz_exit() */ /* TCBが消去されるので,戻り値を書き込んではいけない */ thread_exit(); break; case KZ_SYSCALL_TYPE_WAIT: /* kz_wait() */ p->un.wait.ret = thread_wait(); break; case KZ_SYSCALL_TYPE_SLEEP: /* kz_sleep() */ p->un.sleep.ret = thread_sleep(); break; case KZ_SYSCALL_TYPE_WAKEUP: /* kz_wakeup() */ p->un.wakeup.ret = thread_wakeup(p->un.wakeup.id); break; case KZ_SYSCALL_TYPE_GETID: /* kz_getid() */ p->un.getid.ret = thread_getid(); break; case KZ_SYSCALL_TYPE_CHPRI: /* kz_chpri() */ p->un.chpri.ret = thread_chpri(p->un.chpri.priority); break; case KZ_SYSCALL_TYPE_KMALLOC: /* kz_kmalloc() */ p->un.kmalloc.ret = thread_kmalloc(p->un.kmalloc.size); break; case KZ_SYSCALL_TYPE_KMFREE: /* kz_kmfree() */ p->un.kmfree.ret = thread_kmfree(p->un.kmfree.p); break; case KZ_SYSCALL_TYPE_SEND: /* kz_send() */ p->un.send.ret = thread_send(p->un.send.id, p->un.send.size, p->un.send.p); break; case KZ_SYSCALL_TYPE_RECV: /* kz_recv() */ p->un.recv.ret = thread_recv(p->un.recv.id, p->un.recv.sizep, p->un.recv.pp); break; case KZ_SYSCALL_TYPE_SETINTR: /* kz_setintr() */ p->un.setintr.ret = thread_setintr(p->un.setintr.type, p->un.setintr.handler); break; default: break; } }