int main() { int msock, sel; char *service = "ftp"; enum selection option; printf("Please enter number to select corresponding option:\n"); printf("0: select\n1:fork\n2:thread\n"); scanf("%d", &sel); option = sel; msock = passiveTCP(service, QLEN); switch(option) { case SELECT: printf("SELECT option was selected\n"); do_select(msock); break; case FORK: printf("FORK option was selected\n"); do_fork(msock); break; case THREAD: printf("THREAD option was selected\n"); do_thread(msock); break; default: printf("Invalid option\n"); exit(1); } }
virtual void do_run(TaskData & td, std::unique_ptr<AResult> & ares) override { Threading::CustomRandomData & d = static_cast<Threading::CustomRandomData&>(td); D() << "initial data" << d.get_const(); std::size_t threads_count = d.get_num_threads(); init(threads_count); std::vector<std::thread> threads; threads.reserve(threads_count); for(std::size_t i=0; i<threads_count; ++i) { /* Cant simply use [&](){do_thread()} here. * i will be captured by reference and may be incremented before * passing to do_thread. We need at least [this,i,&d](){} * */ threads.push_back(std::thread([&,i](){do_thread(d, i);})); } for (auto & t : threads) t.join(); std::unique_ptr<Threading::result_type> result(new Threading::result_type(0)); gather_results(*result); ares->set_custom_result(std::move(result)); }
int main(int argc, char **argv) { int x; int threaded; int err; MPI_Comm comms[NTHREADS]; int num_threads_obtained = 1; MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &threaded); if (threaded != MPI_THREAD_MULTIPLE) { printf("unable to initialize with MPI_THREAD_MULTIPLE\n"); goto fn_fail; } for (x = 0; x < NTHREADS; ++x) { MPI_Comm_dup(MPI_COMM_WORLD, &comms[x]); if (x != 0) { err = MTest_Start_thread(do_thread, (void *) &comms[x]); if (err) { /* attempt to continue with fewer threads, we may be on a * thread-constrained platform like BG/P in DUAL mode */ MPI_Comm_free(&comms[x]); break; } ++num_threads_obtained; } } if (num_threads_obtained <= 1) { printf("unable to create any additional threads, exiting\n"); goto fn_fail; } do_thread((void *) &comms[0]); /* we are thread 0 */ err = MTest_Join_threads(); if (err) { printf("error joining threads, err=%d", err); goto fn_fail; } for (x = 0; x < num_threads_obtained; ++x) { MPI_Comm_free(&comms[x]); } fn_exit: MTest_Finalize(err); MPI_Finalize(); return 0; fn_fail: err = 1; goto fn_exit; }
/** @brief Creates a new thread to run func(arg). * * Steps: * 1. Allocate a stack and a thread item(contain thread information)for * the new thread. * 2. Invoke the thread fork system call. * 3. Run the func(arg) in the child thread. * * @param func the function to be run by the child thread. * @param arg the arg fo the func. * @return returns zero on success, and a negative number on error. */ int thr_create(void *(*func)(void *), void * arg) { thread_t *new_thread; int ret; /* * Allocate a stack and a thread item. */ new_thread = prepare_thread(func, arg); if(new_thread == NULL) return ERROR; /* * Invoke the thread fork system call. */ /* Child thread */ if ((ret = thread_fork(GET_STACK(new_thread), (void *)new_thread)) == 0){ /* Run the child thread. */ do_thread(); } /* Parent thread */ else if(ret > 0){ /* * Thread start code */ new_thread->tid = ret; /* Make the child thread running */ make_thread_running(ret, new_thread); mutex_lock(&new_thread->thr_mutex); new_thread->status = RUNNING; mutex_unlock(&new_thread->thr_mutex); /* Return child thread tid */ return ret; } /* * Error happened when fork new thread , recover error . */ /* Recycle stack, new thread */ prepare_thread_rollback(new_thread); return ERROR; }
libearly_init(void) { char *s; int k; s = getenv("EARLY"); if (s == NULL) { printf("%s: EARLY = %s\n", __func__, "(not set)"); return; } printf("%s: EARLY = %s\n", __func__, s); for (k = 0; s[k] != 0; k++) { switch (s[k]) { case 'C': case 'c': do_dlclose(); break; case 'E': case 'e': do_exit(); break; case 'F': case 'f': do_fork(); break; case 'O': case 'o': do_dlopen(); break; case 'T': case 't': do_thread(); break; default: printf("%s: unknown char: %c\n", __func__, s[k]); break; } } }
void interrupt(registers_t *reg) { // The processor responds to a system call interrupt by saving some of // the application's state on the kernel's stack, then jumping to // kernel assembly code (in mpos-int.S, for your information). // That code saves more registers on the kernel's stack, then calls // interrupt(). The first thing we must do, then, is copy the saved // registers into the 'current' process descriptor. current->p_registers = *reg; switch (reg->reg_intno) { case INT_SYS_GETPID: // The 'sys_getpid' system call returns the current // process's process ID. System calls return results to user // code by putting those results in a register. Like Linux, // we use %eax for system call return values. The code is // surprisingly simple: current->p_registers.reg_eax = current->p_pid; run(current); case INT_SYS_FORK: // The 'sys_fork' system call should create a new process. // You will have to complete the do_fork() function! current->p_registers.reg_eax = do_fork(current); run(current); case INT_SYS_YIELD: // The 'sys_yield' system call asks the kernel to schedule a // different process. (MiniprocOS is cooperatively // scheduled, so we need a special system call to do this.) // The schedule() function picks another process and runs it. schedule(); case INT_SYS_EXIT: // 'sys_exit' exits the current process, which is marked as // non-runnable. // The process stored its exit status in the %eax register // before calling the system call. The %eax REGISTER has // changed by now, but we can read the APPLICATION's setting // for this register out of 'current->p_registers'. current->p_state = P_ZOMBIE; current->p_exit_status = current->p_registers.reg_eax; int i =0; for(i = 1; i <NPROCS; i++) { if(proc_array[i].p_state == P_BLOCKED){ proc_array[i].p_state = P_RUNNABLE; } } schedule(); case INT_SYS_WAIT: { // 'sys_wait' is called to retrieve a process's exit status. // It's an error to call sys_wait for: // * A process ID that's out of range (<= 0 or >= NPROCS). // * The current process. // * A process that doesn't exist (p_state == P_EMPTY). // (In the Unix operating system, only process P's parent // can call sys_wait(P). In MiniprocOS, we allow ANY // process to call sys_wait(P).) pid_t p = current->p_registers.reg_eax; if (p <= 0 || p >= NPROCS || p == current->p_pid || proc_array[p].p_state == P_EMPTY) current->p_registers.reg_eax = -1; else if (proc_array[p].p_state == P_ZOMBIE){ current->p_registers.reg_eax = proc_array[p].p_exit_status; proc_array[p].p_state = P_EMPTY; } else //current->p_registers.reg_eax = WAIT_TRYAGAIN; current->p_state = P_BLOCKED; schedule(); } //Clause to handle the sys_newthread system call case INT_SYS_NEWTHREAD: { void (*start)(void) = (void(*)(void)) current->p_registers.reg_eax; current->p_registers.reg_eax = do_thread(start,current); run(current); } //Clause to handle the sys_kill system call case INT_SYS_KILL: { pid_t to_kill = current->p_registers.reg_eax; proc_array[to_kill].p_state = P_EMPTY; run(current); } default: while (1) /* do nothing */; } }
static void processor_apply_func(TaskPool *pool, void *taskdata, int UNUSED(threadid)) { void (*do_thread) (void *) = (void (*) (void *)) BLI_task_pool_userdata(pool); do_thread(taskdata); }