void __ompc_task_create(omp_task_func taskfunc, void* frame_pointer, void *firstprivates, int may_delay, int is_tied, int blocks_parent) { omp_team_t *team; omp_task_t *newtask; __omp_tasks_created++; team = __ompc_get_current_team(); newtask = __ompc_task_get(taskfunc, frame_pointer, firstprivates, __omp_task_stack_size); #if defined(TASK_DEBUG) fprintf(stdout,"%d: __ompc_task_create: %lX created %lX\n", __omp_myid, __omp_current_task->coro, newtask->coro); #endif if(newtask == NULL || newtask->coro == NULL || newtask->desc == NULL ) { fprintf(stderr, "%d: not able to create new tasks\n", __omp_myid); exit(1); } newtask->desc->num_children = 0; newtask->desc->is_parallel_task = 0; newtask->desc->is_tied = is_tied; newtask->desc->may_delay = may_delay; newtask->desc->started = 0; newtask->desc->safe_to_enqueue = 0; newtask->desc->depth = __omp_current_task->desc->depth + 1; newtask->desc->pdepth = newtask->desc->depth; newtask->desc->blocks_parent = blocks_parent; newtask->creator = __omp_current_task; pthread_mutex_init(&newtask->lock, NULL); /* update number of children - use atomic operation if possible */ int x; x = __ompc_atomic_inc(&__omp_current_task->desc->num_children); __ompc_atomic_inc(&(team->num_tasks)); if (blocks_parent) __ompc_atomic_inc(&__omp_current_task->desc->num_blocking_children); if (may_delay & ! (__omp_exe_mode & OMP_EXE_MODE_SEQUENTIAL)) { /* only switch here if newtask will switch back upon initializing its * firstprivates. in that case, when current task resumes it will enqueue * the new task into public queue. */ // __ompc_task_switch(__omp_current_task, newtask); #ifdef SCHED1 newtask->desc->threadid = friend; __sync_bool_compare_and_swap(&__omp_empty_flags[friend], 1, 0); __ompc_task_q_put_tail(&(team->public_task_q[friend]), newtask); #else __ompc_task_q_put_tail(&(team->public_task_q[__omp_myid]), newtask); #endif } else if (__omp_exe_mode & OMP_EXE_MODE_SEQUENTIAL) {
/* __ompc_add_task_to_pool_default: * Adds a task to the task pool. The task will be added to the current * thread's queue. */ int __ompc_add_task_to_pool_default(omp_task_pool_t *pool, omp_task_t *task) { int success; int myid = __omp_myid; omp_task_queue_level_t *per_thread; Is_True(pool != NULL, ("__ompc_add_task_to_pool: task pool is uninitialized")); Is_True(task != NULL, ("__ompc_add_task_to_pool: tried to add NULL task to pool")); /* num_pending_tasks track not just tasks entered into the task pool, but * also tasks marked as deferred that could not fit into the task pool */ if (__ompc_atomic_inc(&pool->num_pending_tasks) == 1) { pthread_mutex_lock(&pool->pool_lock); pthread_cond_broadcast(&pool->pool_cond); pthread_mutex_unlock(&pool->pool_lock); } per_thread = &pool->level[PER_THREAD]; if (__ompc_task_is_tied(task)) /* For tied tasks, we don't use the task_queue API. We explicitly put to * the tail */ success = __ompc_queue_put_tail( &per_thread->task_queue[TIED_IDX(myid)], task); else success = __ompc_task_queue_put( &per_thread->task_queue[UNTIED_IDX(myid)], task); return success; }
/* __ompc_add_task_to_pool_simple_2level: * Adds a task to the task pool. The task will be added to the current * thread's queue. */ int __ompc_add_task_to_pool_simple_2level(omp_task_pool_t *pool, omp_task_t *task) { int success; int myid = __omp_myid; omp_task_queue_level_t *per_thread; omp_task_queue_level_t *community; Is_True(pool != NULL, ("__ompc_add_task_to_pool: task pool is uninitialized")); Is_True(task != NULL, ("__ompc_add_task_to_pool: tried to add NULL task to pool")); success = 0; per_thread = &pool->level[PER_THREAD]; community = &pool->level[COMMUNITY]; /* num_pending_tasks track not just tasks entered into the task pool, but * also tasks marked as deferred that could not fit into the task pool */ if (__ompc_atomic_inc(&pool->num_pending_tasks) == 1) { pthread_mutex_lock(&pool->pool_lock); pthread_cond_broadcast(&pool->pool_cond); pthread_mutex_unlock(&pool->pool_lock); } /* don't try to place it in per-thread queue if it looks to be full, because * we have the community queue to use instead */ if (!__ompc_task_queue_is_full(&per_thread->task_queue[myid])) success = __ompc_task_queue_put(&pool->level[PER_THREAD].task_queue[myid], task); if (!success) success = __ompc_task_queue_donate(pool->level[COMMUNITY].task_queue, task); return success; }
/* __ompc_add_task_to_pool_simple: * Adds a task to the task pool. The task will be added to the current * thread's queue. */ int __ompc_add_task_to_pool_simple(omp_task_pool_t *pool, omp_task_t *task) { int success; int myid = __omp_myid; Is_True(pool != NULL, ("__ompc_add_task_to_pool: task pool is uninitialized")); Is_True(task != NULL, ("__ompc_add_task_to_pool: tried to add NULL task to pool")); /* num_pending_tasks track not just tasks entered into the task pool, but * also tasks marked as deferred that could not fit into the task pool */ if (__ompc_atomic_inc(&pool->num_pending_tasks) == 1) { pthread_mutex_lock(&pool->pool_lock); pthread_cond_broadcast(&pool->pool_cond); pthread_mutex_unlock(&pool->pool_lock); } success = __ompc_task_queue_put(&pool->level[PER_THREAD].task_queue[myid], task); return success; }
void __ompc_task_create(omp_task_func taskfunc, void *frame_pointer, void *firstprivates, int may_delay, int is_tied, int blocks_parent) { int myid; omp_team_t *team; omp_task_t *current_task, *new_task, *orig_task; omp_v_thread_t *current_thread; current_task = __omp_current_task; if (__ompc_task_cutoff()) { //__omp_task_cutoffs++; orig_task = current_task; __omp_current_task = NULL; taskfunc(firstprivates, frame_pointer); __omp_current_task = orig_task; return; /* not reached */ } myid = __omp_myid; current_thread = __omp_current_v_thread; team = current_thread->team; #ifdef USE_COLLECTOR_TASK OMP_COLLECTOR_API_THR_STATE temp_state = (OMP_COLLECTOR_API_THR_STATE)current_thread->state; __ompc_set_state(THR_TASK_CREATE_STATE); __ompc_event_callback(OMP_EVENT_THR_BEGIN_CREATE_TASK); #ifndef OMPT int new_id = __ompc_atomic_inc(&team->collector_task_id); #endif #endif if (may_delay) { new_task = __ompc_task_new(); __ompc_task_set_function(new_task, taskfunc); __ompc_task_set_frame_pointer(new_task, frame_pointer); __ompc_task_set_firstprivates(new_task, firstprivates); new_task->creating_thread_id = myid; new_task->parent = current_task; new_task->depth = current_task->depth + 1; #ifdef USE_COLLECTOR_TASK #ifndef OMPT new_task->task_id = new_id; #endif __omp_collector_task = new_task; __ompc_event_callback(OMP_EVENT_THR_END_CREATE_TASK_DEL); __ompc_set_state(temp_state); #endif __ompc_task_set_flags(new_task, OMP_TASK_IS_DEFERRED); if (is_tied) __ompc_task_set_flags(new_task, OMP_TASK_IS_TIED); __ompc_atomic_inc(¤t_task->num_children); if (blocks_parent) { __ompc_task_set_flags(new_task, OMP_TASK_BLOCKS_PARENT); __ompc_atomic_inc(¤t_task->num_blocking_children); } #ifdef OMPT __ompt_event_callback(ompt_event_task_begin); #endif if (__ompc_add_task_to_pool(team->task_pool, new_task) == 0) { /* couldn't add to task pool, so execute it immediately */ __ompc_task_set_state(current_task, OMP_TASK_READY); __ompc_task_switch(new_task); __ompc_task_set_state(current_task, OMP_TASK_RUNNING); } } else { omp_task_t new_immediate_task; new_task = &new_immediate_task; memset(new_task, 0, sizeof(omp_task_t)); __ompc_task_set_function(new_task, taskfunc); __ompc_task_set_frame_pointer(new_task, frame_pointer); /* firstprivates will be NULL, so don't need to set it */ Is_True(firstprivates == NULL, ("firstprivates should always be NULL")); new_task->creating_thread_id = myid; new_task->parent = current_task; new_task->depth = current_task->depth + 1; #ifdef USE_COLLECTOR_TASK #ifndef OMPT new_task->task_id = new_id; #endif __omp_collector_task = new_task; __ompc_event_callback(OMP_EVENT_THR_END_CREATE_TASK_IMM); #endif if (is_tied) __ompc_task_set_flags(new_task, OMP_TASK_IS_TIED); #ifdef OMPT __ompt_event_callback(ompt_event_task_begin); #endif __ompc_task_set_state(current_task, OMP_TASK_READY); if (__ompc_task_is_tied(current_task)) { /* if current task is tied, it should not go back into task pool */ orig_task = current_task; ++(current_thread->num_suspended_tied_tasks); __omp_current_task = new_task; taskfunc(NULL, frame_pointer); __omp_current_task = orig_task; --(current_thread->num_suspended_tied_tasks); } else { /* if current task is untied, it can go back into task pool, but this * isn't currently supported. */ orig_task = current_task; __omp_current_task = new_task; taskfunc(NULL, frame_pointer); __omp_current_task = orig_task; } __ompc_task_set_state(current_task, OMP_TASK_RUNNING); } }