int main() { int i; syscall_lock_create(&barber_lock); syscall_lock_acquire(&barber_lock); syscall_condition_create(&barber_cond); syscall_condition_create(&standing_cond); syscall_condition_create(&sitting_cond); for(i=0; i<(BARBERS); i++) { barber[i].id = i; syscall_condition_create(&barber[i].cond); syscall_fork((void (*)(int))(&barber_function), (int)&barber[i]); } for(i=0; i<(CUSTOMERS); i++) { customers[i].id = i; syscall_condition_create(&customers[i].cond); syscall_fork((void (*)(int))(&customer_function), (int)&customers[i]); } syscall_lock_release(&barber_lock); syscall_exit(0); return 0; }
void do_syscall(TrapFrame *tf) { int id = tf->eax; switch(id) { case SYS_fork: syscall_fork(tf); break; case SYS_exec: syscall_exec(tf); break; case SYS_exit: syscall_exit(tf); break; case SYS_getpid: syscall_getpid(tf); break; case SYS_waitpid: syscall_waitpid(tf); break; case SYS_puts1: printk((char*)(tf->ebx)); printk(" %d\n", current->pid); break; case SYS_puts: syscall_puts(tf); break; case SYS_read_line: syscall_read_line(tf); break; case SYS_sleep: syscall_sleep(tf); break; case SYS_open: syscall_open(tf); break; case SYS_read: syscall_read(tf); break; case SYS_write: syscall_write(tf); break; case SYS_create: syscall_create(tf); break; case SYS_close: syscall_close(tf); break; case SYS_delete: syscall_delete(tf); break; case SYS_lseek: syscall_lseek(tf); break; case SYS_dup: syscall_dup(tf); break; case SYS_dup2: syscall_dup2(tf); break; case SYS_mkdir: syscall_mkdir(tf); break; case SYS_rmdir: syscall_rmdir(tf); break; case SYS_lsdir: syscall_lsdir(tf); break; case SYS_chdir: syscall_chdir(tf); break; //default: panic("Unknown system call type"); } }
int main() { syscall_lock_create(&baton_lock); syscall_lock_acquire(&baton_lock); // Setup data for threads thread_data data[THREADS]; int i; for(i=0; i<(THREADS); i++) { data[i].id = i; data[i].baton = 0; data[i].countdown = 0; syscall_condition_create(&data[i].cond); data[i].next = &data[(i+1)%THREADS]; syscall_fork((void (*)(int))(&thread_function), (int)&data[i]); } // Setup special data for the first thread data[0].countdown = ROUNDS; data[0].baton = 1; // Start first thread syscall_condition_signal(&data[0].cond, &baton_lock); syscall_lock_release(&baton_lock); syscall_exit(0); return 0; }
void usermode_function(void) { for (int i = 0; i < 100000; i++) { } if (!syscall_fork()) { syscall_thread_exit(0); } else { syscall_thread_exit(0); } }
int main() { /* 2**10 should be plenty! */ int i = 0; for (; i < 10; i++) { pid_t pid = syscall_fork(); if (pid < 0) { /* This will probably be printed multiple times, since multiple children will have tried to call `syscall_fork`. */ puts("A negative value was returned!\n"); } } return 0; }
static void main_loop() { char* line, cmd, arg1; char buffer[81]; char command[81]; char args[16][81]; while (running) { line = (char*) readline(buffer); memset(command, 0, sizeof(command)); memset(args[0], 0, sizeof(args[0])); token(line, 1, command); token(line, 2, args[0]); if (strlen(command) > 1) { puts("The command is "); puts(command); puts("\n"); } if (strlen(args[0]) > 1) { puts("The first parameter is "); puts(args[0]); puts("\n"); } if (command && strncmp(command, "EXIT", strlen(command))) { puts("Exit command\n"); running = 0; } if (command && args[0] && strncmp(command, "EXEC", strlen(command))) { if (!syscall_fork()) { if (!exec(&args[0])) { puts("Error.\n"); syscall_exit(); } } } } puts("Exiting...\n"); syscall_exit(); }
int main() { syscall_lock_create(&print_lock); int i; while (1) { for (i = 0; i < NUM_THREADS; i++) { switch (thread_status[i]) { case THREAD_START: thread_status[i] = THREAD_STARTED; syscall_fork(countup, i); break; case THREAD_STARTSOON: thread_status[i] = THREAD_START; break; } } } return counter; }
int main() { int i; for (i = 0; i < NUM_THREADS; ++i) { A[i] = 0; done[i] = 0; threads[i] = syscall_fork(&test, i); } for (i = 0; i < NUM_THREADS; ++i) { while (!done[i]) ; } for (i = 0; i < NUM_THREADS; ++i) { printf("Thread %d: %d\n", i, A[i]); } return 0; }
/** * 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. */ switch(user_context->cpu_regs[MIPS_REGISTER_A0]) { case SYSCALL_HALT: halt_kernel(); break; case SYSCALL_EXIT: syscall_exit(user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_WRITE: user_context->cpu_regs[MIPS_REGISTER_V0] = syscall_write(user_context->cpu_regs[MIPS_REGISTER_A1], (char*)user_context->cpu_regs[MIPS_REGISTER_A2], (user_context->cpu_regs[MIPS_REGISTER_A3])); break; case SYSCALL_READ: user_context->cpu_regs[MIPS_REGISTER_V0] = syscall_read(user_context->cpu_regs[MIPS_REGISTER_A1], (char*)user_context->cpu_regs[MIPS_REGISTER_A2], (user_context->cpu_regs[MIPS_REGISTER_A3])); break; case SYSCALL_JOIN: user_context->cpu_regs[MIPS_REGISTER_V0] = syscall_join(user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_EXEC: user_context->cpu_regs[MIPS_REGISTER_V0] = syscall_exec((char*)user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_FORK: user_context->cpu_regs[MIPS_REGISTER_V0] = syscall_fork((void (*)(int))user_context->cpu_regs[MIPS_REGISTER_A1], user_context->cpu_regs[MIPS_REGISTER_A2]); break; case SYSCALL_LOCK_CREATE: user_context->cpu_regs[MIPS_REGISTER_V0] = syscall_lock_create((lock_t*) user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_LOCK_ACQUIRE: syscall_lock_acquire((lock_t*) user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_LOCK_RELEASE: syscall_lock_release((lock_t*) user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_CONDITION_CREATE: user_context->cpu_regs[MIPS_REGISTER_V0] = syscall_condition_create((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1]); break; case SYSCALL_CONDITION_WAIT: syscall_condition_wait((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1], (lock_t*) user_context->cpu_regs[MIPS_REGISTER_A2]); break; case SYSCALL_CONDITION_SIGNAL: syscall_condition_signal((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1], (lock_t*) user_context->cpu_regs[MIPS_REGISTER_A2]); break; case SYSCALL_CONDITION_BROADCAST: syscall_condition_broadcast((cond_t*) user_context->cpu_regs[MIPS_REGISTER_A1], (lock_t*) user_context->cpu_regs[MIPS_REGISTER_A2]); break; default: KERNEL_PANIC("Unhandled system call\n"); } /* Move to next instruction after system call */ user_context->pc += 4; }
/* Fork. Duh. */ int fork(void) { return syscall_fork(); }