int Message::receive(MessageInfo* info) { int result = syscall_receive(info); if (result != M_OK) { syscall_mthread_yield_message(); result = syscall_receive(info); } return result; }
PUBLIC void syscall_handle(void) { struct proc* target_proc; pid_t pid; u32_t syscall_num; u8_t res; arch_printf("syscall_handle\n"); struct thread* th = cur_th; /* Get current thread */ if (th == NULL) { res = IPC_FAILURE; goto end; } /* Get syscall number from source register */ syscall_num = arch_ctx_get((arch_ctx_t*)th, ARCH_CONST_SOURCE); /* Put originator proc into source register instead */ arch_ctx_set((arch_ctx_t*)th, ARCH_CONST_SOURCE,th->proc->pid); /* Destination proc, stored in EDI */ pid = (pid_t)arch_ctx_get((arch_ctx_t*)th, ARCH_CONST_DEST); if ( pid == IPC_ANY) { target_proc = NULL; } else { /* Get proc structure from given id */ target_proc = proc_pid(pid); if ( target_proc == NULL ) { res = IPC_FAILURE; goto end; } } /* Dispatch call to effective primitives */ switch(syscall_num) { case SYSCALL_SEND: { res = syscall_send(th, target_proc); break; } case SYSCALL_RECEIVE: { res = syscall_receive(th, target_proc); break; } case SYSCALL_NOTIFY: { res = syscall_notify(th, target_proc); break; } default: { arch_printf("not a syscall number\n"); res = IPC_FAILURE; break; } } end: /* Set result in caller's return register */ arch_ctx_set((arch_ctx_t*)th, ARCH_CONST_RETURN,res); arch_printf("end of syscall :%u\n",arch_ctx_get((arch_ctx_t*)th, ARCH_CONST_RETURN)); return; }