Esempio n. 1
0
Scheduler::PhysicalTaskPtr
Scheduler::take_runnable_task(const Locality &locality){
	const auto tid = locality.self_thread_id();
	PhysicalTaskPtr task;
	// try to take an unstealable task
	task = take_unstealable_task(locality);
	if(task){ return task; }
	// try to take a local stealable task
	task = take_local_stealable_task(locality);
	if(task){ return task; }
	// try to steal an task
	task = steal_task(locality);
	if(task){ return task; }
	// attempt to sleep
	auto &sync = m_synchronizers[tid];
	while(true){
		sync.set_is_sleeping();
		if(task || is_finished() || is_cancelled()){ break; }
		// try to take an unstealable task
		task = take_unstealable_task(locality);
		if(task){ break; }
		// try to steal an task
		task = steal_task(locality);
		if(task){ break; }
		// wait for new task
		sync.wait();
	}
	sync.reset_is_sleeping();
	return task;
}
Esempio n. 2
0
        void run_core(std::size_t core_id)
        {
            task_pack<TASK> tmp_task;

            while(cores_[core_id].running)
            {
                if(cores_[core_id].queue_size() > 0)
                { // Still has unfinished tasks.
                    cores_[core_id].execute(this);
                }
                else if(can_steal())
                { // Steal from other cores (at random).
                    try
                    {
                        tmp_task = steal_task();
                    }
                    catch(...)
                    {
                        // The queue got emptied before steal_task() could
                        // finnish.
                        cores_[core_id].running = false;
                        break;
                    }

                    cores_[core_id].add_task(std::move(tmp_task));
                    cores_[core_id].execute(this);
                }
                else
                { // No task in the entire schedulet that could be run
                  // by this core.
                    cores_[core_id].running = false;
                }
            }
        }
Esempio n. 3
0
/** Steal work from another worker's task stack */
static int steal(struct generic_task_desc * _tweed_top_, 
                 struct worker_desc * victim) {
    struct generic_task_desc * stolenTask;
    struct worker_desc * me = (struct worker_desc *) thread_get_tls();
            
    LOCK(victim->lock);      

    stolenTask = victim->bot;
    // check if there is actually work to steal
    if (stolenTask != NULL && stolenTask->balarm == TWEED_TASK_NEW) {
        
        // try to steal task
        tweed_task_func_t func = steal_task(stolenTask, me);
        
        if (func == NULL) {
            // we didn't succeed in the steal, back off
#ifndef TWEED_USE_CAS
            stolenTask->balarm  = TWEED_TASK_INLINED;
            stolenTask->thief = NULL;
#endif
            UNLOCK(victim->lock);
            return 0; // didn't steal anything 
        } else {
            // we have stolen the task, update bot
            atomic_inc(&(victim->bot), stolenTask->size);
            UNLOCK(victim->lock);

            // and run task
            trace_event(TRACE_SUBSYS_TWEED, TRACE_EVENT_TWEED_STEAL, victim->core_id);
            func(_tweed_top_, stolenTask);
            trace_event(TRACE_SUBSYS_TWEED, TRACE_EVENT_TWEED_STEAL_END,
                        victim->core_id);
            
            // signal task completion
            stolenTask->balarm |= TWEED_TASK_COMPLETE;
            return 1;
        }      
    } else {
        UNLOCK(victim->lock);
        return 0; // didn't steal anything   
    }
}