static int ws_push_task(struct starpu_task *task) { unsigned sched_ctx_id = task->sched_ctx; struct _starpu_work_stealing_data *ws = (struct _starpu_work_stealing_data*)starpu_sched_ctx_get_policy_data(sched_ctx_id); struct _starpu_deque_jobq *deque_queue; struct _starpu_job *j = _starpu_get_job_associated_to_task(task); int workerid = starpu_worker_get_id(); unsigned worker = 0; struct starpu_worker_collection *workers = starpu_sched_ctx_get_worker_collection(sched_ctx_id); struct starpu_sched_ctx_iterator it; workers->init_iterator(workers, &it); /* !! C'est ballot de tout locker! */ while(workers->has_next(workers, &it)) { worker = workers->get_next(workers, &it); starpu_pthread_mutex_t *sched_mutex; starpu_pthread_cond_t *sched_cond; starpu_worker_get_sched_condition(worker, &sched_mutex, &sched_cond); STARPU_PTHREAD_MUTEX_LOCK(sched_mutex); } /* If the current thread is not a worker but * the main thread (-1), we find the better one to * put task on its queue */ if (workerid == -1) workerid = select_worker(sched_ctx_id); deque_queue = ws->queue_array[workerid]; #ifdef HAVE_AYUDAME_H if (AYU_event) { intptr_t id = workerid; AYU_event(AYU_ADDTASKTOQUEUE, j->job_id, &id); } #endif _starpu_job_list_push_back(&deque_queue->jobq, j); deque_queue->njobs++; starpu_push_task_end(task); while(workers->has_next(workers, &it)) { worker = workers->get_next(workers, &it); starpu_pthread_mutex_t *sched_mutex; starpu_pthread_cond_t *sched_cond; starpu_worker_get_sched_condition(worker, &sched_mutex, &sched_cond); #ifndef STARPU_NON_BLOCKING_DRIVERS STARPU_PTHREAD_COND_SIGNAL(sched_cond); #endif STARPU_PTHREAD_MUTEX_UNLOCK(sched_mutex); } return 0; }
void callback(void *arg) { unsigned *received = arg; STARPU_PTHREAD_MUTEX_LOCK(&mutex); *received = *received + 1; FPRINTF_MPI(stderr, "Requests %d received\n", *received); STARPU_PTHREAD_COND_SIGNAL(&cond); STARPU_PTHREAD_MUTEX_UNLOCK(&mutex); }
/* Note: in case of a tag, it must be already locked */ void _starpu_notify_cg(struct _starpu_cg *cg) { STARPU_ASSERT(cg); unsigned remaining = STARPU_ATOMIC_ADD(&cg->remaining, -1); if (remaining == 0) { cg->remaining = cg->ntags; struct _starpu_tag *tag; struct _starpu_cg_list *tag_successors, *job_successors; struct _starpu_job *j; /* the group is now completed */ switch (cg->cg_type) { case STARPU_CG_APPS: { /* this is a cg for an application waiting on a set of * tags, wake the thread */ STARPU_PTHREAD_MUTEX_LOCK(&cg->succ.succ_apps.cg_mutex); cg->succ.succ_apps.completed = 1; STARPU_PTHREAD_COND_SIGNAL(&cg->succ.succ_apps.cg_cond); STARPU_PTHREAD_MUTEX_UNLOCK(&cg->succ.succ_apps.cg_mutex); break; } case STARPU_CG_TAG: { tag = cg->succ.tag; tag_successors = &tag->tag_successors; tag_successors->ndeps_completed++; /* Note: the tag is already locked by the * caller. */ if ((tag->state == STARPU_BLOCKED) && (tag_successors->ndeps == tag_successors->ndeps_completed)) { /* reset the counter so that we can reuse the completion group */ tag_successors->ndeps_completed = 0; _starpu_tag_set_ready(tag); } break; } case STARPU_CG_TASK: { j = cg->succ.job; STARPU_PTHREAD_MUTEX_LOCK(&j->sync_mutex); job_successors = &j->job_successors; unsigned ndeps_completed = STARPU_ATOMIC_ADD(&job_successors->ndeps_completed, 1); STARPU_ASSERT(job_successors->ndeps >= ndeps_completed); /* Need to atomically test submitted and check * dependencies, since this is concurrent with * _starpu_submit_job */ if (j->submitted && job_successors->ndeps == ndeps_completed && j->task->status == STARPU_TASK_BLOCKED_ON_TASK) { /* That task has already passed tag checks, * do not do them again since the tag has been cleared! */ _starpu_enforce_deps_starting_from_task(j); } else STARPU_PTHREAD_MUTEX_UNLOCK(&j->sync_mutex); break; } default: STARPU_ABORT(); } } }