diff -ruN kozos38/kozos.h kozos39/kozos.h --- kozos38/kozos.h Mon Jan 26 22:57:44 2009 +++ kozos39/kozos.h Sun Feb 1 19:44:01 2009 @@ -27,6 +27,12 @@ void *kz_memalloc(int size); int kz_memfree(void *p); +/* srvcall */ +int kx_wakeup(int id); +int kx_send(int id, int size, char *p); +void *kx_kmalloc(int size); +int kx_kmfree(void *p); + /* library */ void kz_start(kz_func func, char *name, int pri, int argc, char *argv[]); void kz_sysdown(); diff -ruN kozos38/syscall.c kozos39/syscall.c --- kozos38/syscall.c Mon Jan 26 22:57:44 2009 +++ kozos39/syscall.c Sun Feb 1 19:44:01 2009 @@ -15,6 +15,8 @@ return; } +/* System Call */ + int kz_run(kz_func func, char *name, int pri, int argc, char *argv[]) { kz_syscall_param_t param; @@ -160,4 +162,40 @@ param.un.memfree.p = p; kz_syscall(KZ_SYSCALL_TYPE_MEMFREE, ¶m); return param.un.memfree.ret; +} + +/* Service Call */ + +int kx_wakeup(int id) +{ + kz_syscall_param_t param; + param.un.wakeup.id = id; + kz_srvcall(KZ_SYSCALL_TYPE_WAKEUP, ¶m); + return param.un.wakeup.ret; +} + +int kx_send(int id, int size, char *p) +{ + kz_syscall_param_t param; + param.un.send.id = id; + param.un.send.size = size; + param.un.send.p = p; + kz_srvcall(KZ_SYSCALL_TYPE_SEND, ¶m); + return param.un.send.ret; +} + +void *kx_kmalloc(int size) +{ + kz_syscall_param_t param; + param.un.kmalloc.size = size; + kz_srvcall(KZ_SYSCALL_TYPE_KMALLOC, ¶m); + return param.un.kmalloc.ret; +} + +int kx_kmfree(void *p) +{ + kz_syscall_param_t param; + param.un.kmfree.p = p; + kz_srvcall(KZ_SYSCALL_TYPE_KMFREE, ¶m); + return param.un.kmfree.ret; } diff -ruN kozos38/syscall.h kozos39/syscall.h --- kozos38/syscall.h Mon Jan 26 22:57:44 2009 +++ kozos39/syscall.h Sun Feb 1 19:44:01 2009 @@ -106,5 +106,6 @@ } kz_syscall_param_t; void kz_syscall(kz_syscall_type_t type, kz_syscall_param_t *param); +void kz_srvcall(kz_syscall_type_t type, kz_syscall_param_t *param); #endif diff -ruN kozos38/thread.c kozos39/thread.c --- kozos38/thread.c Mon Jan 26 22:57:44 2009 +++ kozos39/thread.c Sun Feb 1 19:44:01 2009 @@ -23,7 +23,6 @@ static kz_handler handlers[SIG_NUM]; static int debug_sockt = 0; sigset_t block; -static sigset_t block_sys; static sigset_t block_old; static int block_count = 0; static stack_t intrstack; @@ -265,25 +264,8 @@ static void extintr_proc(int signo) { - /* - * システムコールのパラメータ格納にコンテキストが必要なので, - * 割り込み処理用のコンテキストを確保する. - * (割り込みがネストしたときのために,スタック上に確保する) - */ - kz_thread intrcontext; - kz_thread *current_save; - - if (handlers[signo]) { - memset(&intrcontext, 0, sizeof(intrcontext)); - current_save = current; - current = &intrcontext; - - sigprocmask(SIG_UNBLOCK, &block_sys, NULL); + if (handlers[signo]) handlers[signo](signo); - sigprocmask(SIG_BLOCK, &block_sys, NULL); - - current = current_save; - } if (sigcalls[signo]) sendmsg(sigcalls[signo], 0, 0, NULL); } @@ -333,10 +315,8 @@ return 0; } -static void syscall_proc(kz_syscall_type_t type, kz_syscall_param_t *p) +static void syscall_procedure(kz_syscall_type_t type, kz_syscall_param_t *p) { - getcurrent(); - /* システムコールの実行中にcurrentが書き換わるので注意 */ switch (type) { case KZ_SYSCALL_TYPE_RUN: @@ -402,6 +382,17 @@ return; } +static void syscall_proc(kz_syscall_type_t type, kz_syscall_param_t *p) +{ + getcurrent(); + syscall_procedure(type, p); +} + +static void srvcall_proc(kz_syscall_type_t type, kz_syscall_param_t *p) +{ + syscall_procedure(type, p); +} + static void schedule() { #if PRI_NUM > 32 @@ -436,6 +427,8 @@ static void thread_intrvec(int signo, kz_thread *thp) { + kz_thread *current_old; + switch (signo) { case SIGSYS: /* システムコール */ syscall_proc(thp->syscall.type, thp->syscall.param); @@ -469,12 +462,28 @@ return; } - schedule(); + current_old = NULL; + while (1) { + schedule(); + + if (current_old && (current == current_old)) + break; + + current_old = current; + + if (current->precall) { + current->precall((int)current); + } else if (default_precall) { + default_precall((int)current); + } else { + break; + } - if (current->precall) { - current->precall((int)current); - } else if (default_precall) { - default_precall((int)current); + /* + * 上記 precall の呼び出し内部でサービスコールが呼ばれて current が + * 書きかわっていたり,もっと優先度の高いスレッドがレディー状態に + * なっている可能性があるので,スケジューリングしなおす. + */ } /* @@ -559,9 +568,6 @@ sigaddset(&block, SIGTRAP); sigaddset(&block, SIGILL); - sigemptyset(&block_sys); - sigaddset(&block_sys, SIGSYS); - thread_start(func, name, pri, argc, argv); /* ここには返ってこない */ @@ -600,4 +606,10 @@ sigprocmask(SIG_SETMASK, &block_old, NULL); } } +} + +void kz_srvcall(kz_syscall_type_t type, kz_syscall_param_t *param) +{ + srvcall_proc(type, param); + return; }