static void execute__rx(struct bomp_binding *_binding, uint64_t fn, uint64_t arg, uint32_t tid, uint64_t icv_task) { struct bomp_thread *t = _binding->st; struct bomp_tls *tls = thread_get_tls(); BOMP_DEBUG_THREAD("execute__rx: %p %p, %lx\n", t, tls, icv_task); assert(t == &tls->r.thread); struct omp_icv_task icvt; memcpy(&icvt, (void *)icv_task, sizeof(struct omp_icv_task)); bomp_icv_set_task(&icvt); tls->thread_id = tid; bomp_thread_fn_t func= (bomp_thread_fn_t)fn; // calling the function func((void *)arg); bomp_icv_set_task(NULL); tls->thread_id = -1; struct txq_msg_st *msg_st = txq_msg_st_alloc(&t->txq); if (msg_st == NULL) { BOMP_ERROR("allocation of message state failed: %" PRIu32 "\n", tid); return; } msg_st->send = done__tx; msg_st->err = SYS_ERR_OK; txq_send(msg_st); }
void GOMP_parallel_start(void (*fn)(void *), void *data, unsigned nthreads) { debug_printf("GOMP_parallel_start(%p, %p, %u)\n", fn, data, nthreads); /* Identify the number of threads that can be spawned and start the processing */ if (!omp_in_parallel()) { debug_printf("not in parallel\n"); struct omp_icv_task *icv_task = bomp_icv_task_new(); if (!icv_task) { debug_printf("no icv task\n"); return; } icv_task->active_levels = 1; icv_task->nthreads = omp_get_max_threads(); debug_printf("omp_get_max_threads = %u\n", icv_task->nthreads); if (nthreads == 0 || (icv_task->dynamic && icv_task->nthreads < nthreads)) { icv_task->nthreads = OMP_GET_ICV_GLOBAL(thread_limit); debug_printf("resetting to = %u\n", icv_task->nthreads); } bomp_icv_set_task(icv_task); debug_printf("icv task set %u\n", icv_task->nthreads); /* start processing */ bomp_start_processing(fn, data, 0, icv_task->nthreads); } else { if (omp_get_nested()) { // handle nested paralellism assert(!"Handling nested paralellism\n"); } /* we have already started enough threads */ uint32_t active_levels = OMP_GET_ICV_TASK(active_levels); //debug_printf("setting active_levels to %u\n", active_levels+1); OMP_SET_ICV_TASK(active_levels, active_levels+1); } }