Esempio n. 1
0
// The master's scheduler.
// It behaves as follows:
// First, check conflicts withe previous cmds:
// -- If any, look at the pending queue:
// 		-- If FULL, return -1.
// 		-- Else, return 0;
// -- If none, call the select_worker() to return the worker id.
static int scheduler(uint64_t cmd_id){
	
	if (check_conflict(cmd_id) == 1){
		if (master_pending.cnt == PENDING_QUEUE_SIZE) return -2;

		if (master_pending.tail == NULL){
		 	master_pending.tail = malloc(sizeof(struct pending_task));
			master_pending.head = master_pending.tail;
			master_pending.tail->prev = NULL;
			master_pending.tail->next = NULL;
			master_pending.cnt = 1;
		} else{
			master_pending.cnt += 1;
			master_pending.tail->next = malloc(sizeof(struct pending_task));
			master_pending.tail->next->next = NULL;
			master_pending.tail->next->prev = master_pending.tail;
			master_pending.tail = master_pending.tail->next;
		}
		master_pending.tail->cmd_id = cmd_id;
		
		pending_count += 1;
		return -1;
	}
	
	return select_worker();
}
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;
}
Esempio n. 3
0
// Clear the pending queue.
static void clear_pending(void){
	if (master_pending.cnt == 0) return;
	int cnt = 0;	
	struct pending_task *target = master_pending.head;
	while (target){
		int cflag = 0;
		uint64_t cmd_id = master_pending.head->cmd_id;
		
		// If head cmd still cannot issue, just return
		if (check_issue_conflict(cmd_id)) cflag = 1;	
		if (!cflag){
			struct pending_task *cp_ptr = master_pending.head;
			while (cp_ptr != target){
				if (check_cover(cp_ptr->cmd_id, cmd_id)){
					cflag = 1;
					break;
				}
				cp_ptr = cp_ptr->next;
			}
		}
		if (cflag){
			target = target -> next;
			continue;
		}
		cnt += 1;
		// Here we issue first so that
		// the worker would receive all the cmds from the buf.
		int rc = select_worker();
		master_issue(cmd_id, rc);		

		master_pending.cnt -= 1;	
		struct pending_task *back_target = target->next;
		if (target->prev) target->prev->next = target->next;
		if (target->next) target->next->prev = target->prev;
		if (target == master_pending.head) master_pending.head = target->next;
		if (target == master_pending.tail) master_pending.tail = target->prev;
		free(target);
		target = back_target;
	}
}