int main(int argc, char *argv[]) { void *result; char *data = strdup("Hello world!\n"); struct thread_info *ti = newthread(hello_thread); // Send one line of text. thread_send(ti, data, strlen(data)); // Signal thread to exit and wait for it to do so. thread_send(ti, NULL, 1); pthread_join(ti->thread, &result); return (long)result; }
struct thread *fault_page(struct thread *image) { uint32_t cr2; /* Get faulting address from register CR2 */ cr2 = cpu_get_cr2(); /* If in kernelspace, panic */ if ((image->cs & 0x3) == 0) { /* i.e. if it was kernelmode */ debug_printf("page fault at %x, ip = %x, frame %x, esp = %x\n", cr2, image->eip, page_get(cr2), image->esp); debug_panic("page fault exception"); } if (cr2 >= image->stack && cr2 < image->stack + SEGSZ) { /* allocate stack */ mem_alloc(cr2 & ~0xFFF, PAGESZ, PF_PRES | PF_RW | PF_USER); return image; } else { /* fault */ debug_printf("%d: %s: page fault at %x, ip = %x, frame %x\n", image->proc->pid, image->proc->name, cr2, image->eip, page_get(cr2)); debug_printf("user stack: %x - %x\n", image->stack, image->stack + SEGSZ); debug_printf("user stack dump: (ebp = %x)\n", image->ebp); debug_dumpi((void*) image->useresp, 30); process_freeze(image->proc); return thread_send(image, image->proc->pid, PORT_PAGE, NULL); } }
struct thread *fault_generic(struct thread *image) { /* If in kernelspace, panic */ if ((image->cs & 0x3) == 0) { debug_printf("EIP:%x NUM:%d ERR:%x\n", image->eip, image->num, image->err); debug_panic("unknown exception"); } process_freeze(image->proc); return thread_send(image, image->proc->pid, PORT_ILL, NULL); }
void thread_sendv(uint64_t target, uint64_t source, portid_t port) { struct thread *thread; thread = thread_send(NULL, target, port, NULL); if (!thread || thread->proc->pid != (uint32_t) target) { return; } thread->esi = source; thread->edi = source >> 32; thread->ebx = target >> 32; }
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; } }
static void call_functions(kz_syscall_type_t type, kz_syscall_param_t *p) { switch(type){ case KZ_SYSCALL_TYPE_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: thread_exit(); break; case KZ_SYSCALL_TYPE_WAIT: p->un.wait.ret = thread_wait(); break; case KZ_SYSCALL_TYPE_SLEEP: p->un.sleep.ret = thread_sleep(); break; case KZ_SYSCALL_TYPE_WAKEUP: p->un.wakeup.ret = thread_wakeup(p->un.wakeup.id); break; case KZ_SYSCALL_TYPE_GETID: p->un.getid.ret = thread_getid(); break; case KZ_SYSCALL_TYPE_CHPRI: p->un.chpri.ret = thread_chpri(p->un.chpri.priority); break; case KZ_SYSCALL_TYPE_KMALLOC: p->un.kmalloc.ret = thread_kmalloc(p->un.kmalloc.size); break; case KZ_SYSCALL_TYPE_KMFREE: p->un.kmfree.ret = thread_kmfree(p->un.kmfree.p); break; case KZ_SYSCALL_TYPE_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: p->un.recv.ret = thread_recv(p->un.recv.id, p->un.recv.sizep, p->un.recv.pp); break; default: break; } }
struct thread *syscall_exit(struct thread *image) { struct thread *new_image; uint16_t pid; uint32_t parent; pid = image->proc->pid; if (pid == 1) { debug_panic("init died"); } parent = image->proc->parent->pid; process_switch(process_get(1)); new_image = thread_send(image, parent, PORT_CHILD, NULL); image->proc->status = image->eax; process_kill(image->proc); return new_image; }
void *thread_send_fun(void *arg) { return thread_send(arg); }
struct thread *irq_redirect(struct thread *image) { return thread_send(NULL, irq_holder[INT2IRQ(image->num)], PORT_IRQ, NULL); }