void init_startup_thread(uint32_t arg) { /* Threads have arguments for functions they run, we don't need any. Silence the compiler warning by using the argument. */ arg = arg; kprintf("Mounting filesystems\n"); vfs_mount_all(); kprintf("Initializing networking\n"); network_init(); if(bootargs_get("initprog") == NULL) { kprintf("No initial program (initprog), dropping to fallback\n"); init_startup_fallback(); } kprintf("Starting initial program '%s'\n", bootargs_get("initprog")); /* `process_start` no longer takes an executable as its argument, so we need to start initprog with `process_spawn`. */ process_id_t pid = process_spawn(bootargs_get("initprog")); if (pid < 0) { KERNEL_PANIC("Couldn't fit initial program in process table.\n"); } process_join(pid); /* The current process_start() should never return. */ KERNEL_PANIC("Run out of initprog.\n"); }
void init_startup_thread(uint32_t arg) { /* Threads have arguments for functions they run, we don't need any. Silence the compiler warning by using the argument. */ arg = arg; process_id_t pid; kprintf("Mounting filesystems\n"); vfs_mount_all(); kprintf("Initializing networking\n"); network_init(); if(bootargs_get("initprog") == NULL) { kprintf("No initial program (initprog), dropping to fallback\n"); init_startup_fallback(); } kprintf("Starting initial program '%s'\n", bootargs_get("initprog")); pid = process_spawn(bootargs_get("initprog")); if (pid < 0) KERNEL_PANIC("Couldn't fit initial program in process table.\n"); process_join(pid); halt_kernel(); }
static void process_cmd(const string &ip, const string &data, string &answer) { switch(data[0]) { case 'J': { cout << "Command join received" << endl; process_join(ip, answer); break; } case 'G': { cout << "Command get_subset received" << endl; process_get_subset(ip, answer); break; } case 'P': { cout << "Command publish received" << endl; process_publish(ip, data, answer); break; } default: { cout << "Unknown command " << data[0] << " from " << ip << endl; exit(-1); } } }
/** * Handle system calls. Interrupts are enabled when this function is * called. * * @param user_context The userland context (CPU registers as they * where when system call instruction was called in userland) */ void syscall_handle(context_t *user_context) { /* When a syscall is executed in userland, register a0 contains * the number of the syscall. Registers a1, a2 and a3 contain the * arguments of the syscall. The userland code expects that after * returning from the syscall instruction the return value of the * syscall is found in register v0. Before entering this function * the userland context has been saved to user_context and after * returning from this function the userland context will be * restored from user_context. */ int retval; switch(user_context->cpu_regs[MIPS_REGISTER_A0]) { case SYSCALL_HALT: halt_kernel(); break; case SYSCALL_EXEC: retval = (int) process_spawn((char*) user_context->cpu_regs[MIPS_REGISTER_A1]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; case SYSCALL_EXIT: /* Resources are cleaned up in process_finish(...) */ process_finish(user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_JOIN: retval = process_join(user_context->cpu_regs[MIPS_REGISTER_A1]); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; break; case SYSCALL_READ: { int fhandle = user_context->cpu_regs[MIPS_REGISTER_A1]; int buffer = user_context->cpu_regs[MIPS_REGISTER_A2]; int length = user_context->cpu_regs[MIPS_REGISTER_A3]; int retval = syscall_read(fhandle, (void *)buffer, length); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; } break; case SYSCALL_WRITE: { int fhandle = user_context->cpu_regs[MIPS_REGISTER_A1]; int buffer = user_context->cpu_regs[MIPS_REGISTER_A2]; int length = user_context->cpu_regs[MIPS_REGISTER_A3]; int retval = syscall_write(fhandle, (void *)buffer, length); user_context->cpu_regs[MIPS_REGISTER_V0] = retval; } break; default: KERNEL_PANIC("Unhandled system call\n"); } /* Move to next instruction after system call */ user_context->pc += 4; }
/** * Handle system calls. Interrupts are enabled when this function is * called. */ uintptr_t syscall_entry(uintptr_t syscall, uintptr_t arg0, uintptr_t arg1, uintptr_t arg2) { arg0 = arg0; arg1 = arg1; arg2 = arg2; /* When a syscall is executed in userland, register a0 contains * the number of the syscall. Registers a1, a2 and a3 contain the * arguments of the syscall. The userland code expects that after * returning from the syscall instruction the return value of the * syscall is found in register v0. Before entering this function * the userland context has been saved to user_context and after * returning from this function the userland context will be * restored from user_context. */ switch(syscall) { case SYSCALL_HALT: halt_kernel(); break; case SYSCALL_READ: return syscall_read((void*)arg1); break; case SYSCALL_WRITE: return syscall_write((const void*)arg1, (int)arg2); break; case SYSCALL_SPAWN: return syscall_spawn((char const*)arg0, (void*) arg1); break; case SYSCALL_EXIT: syscall_exit((int)arg0); break; case SYSCALL_JOIN: return process_join((int)arg0); break; default: KERNEL_PANIC("Unhandled system call\n"); } return 0; }
int syscall_join(int pid){ int retval = process_join(pid); return retval; }
int syscall_join(int pid) { return process_join((process_id_t) pid); }
int syscall_join(process_id_t pid) { return process_join(pid); }
int join (int pid) { return process_join((process_id_t) pid); }