void AffinityTask::combinePossibleTaskSet_recursive(const std::unordered_map<CPUID, std::list<TaskSet>>& possibleReplacement, const std::unordered_map<CPUID, CPUID>& nextCPU, const CPUID& currentCPU, const std::list<TaskSet>& visited, std::list<TaskSet>& saveAt)
{

	auto currentList = possibleReplacement.find(currentCPU);
	auto nextCPUIter = nextCPU.find(currentCPU);
	if(nextCPUIter == nextCPU.end())
	{
		//time to print
		for(auto currentItem : currentList->second)
		{
			TaskSet returnSet;
			for(auto curStack : visited)
			{
				for(auto task : curStack)
					returnSet.insert(task);
			}
			for(auto task : currentItem)
				returnSet.insert(task);
			saveAt.push_back(returnSet);
		}
	}
	else
	{
		auto nextCPUID = nextCPUIter->second;
		for(auto currentItem : currentList->second)
		{
			std::list<TaskSet> newVisited(visited);
			newVisited.push_back(currentItem);

			combinePossibleTaskSet_recursive(
					possibleReplacement, nextCPU, nextCPUID, newVisited, saveAt);
		}
	}
}
Ejemplo n.º 2
0
void
TaskRunner::getReadyTasks(const InitializerTask::SP task, TaskList &readyTasks, TaskSet &checked)
{
    if (task->getState() != State::BLOCKED) {
        return; // task running or done, all dependencies done
    }
    if (!checked.insert(task.get()).second) {
        return; // task already checked from another depender
    }
    const TaskList &deps = task->getDependencies();
    bool ready = true;
    for (const auto &dep : deps) {
        switch (dep->getState()) {
        case State::RUNNING:
            ready = false;
            break;
        case State::DONE:
            break;
        case State::BLOCKED:
            ready = false;
            getReadyTasks(dep, readyTasks, checked);
        }
    }
    if (ready) {
        readyTasks.push_back(task);
    }
}
bool AffinityTask::staticStrongAnalysis(const TaskSet& taskSet, Time overhead)
{
	AffinityTask::Compare compare;
	std::unordered_map<AffinityTask*, Time> responseTime;
	Affinity allCPU;
	for(AffinityTask* task : taskSet)
	{
		responseTime.insert(std::pair<AffinityTask*, Time>(task, task->worstExecution));
		for(auto cpu : task->affinity)
			allCPU.insert(cpu);
	}

	while(true)
	{
		bool changed = false;
		bool overflow = false;
		std::unordered_map<AffinityTask*, Time> newResponseTime;

		for(auto current : responseTime)
		{
			AffinityTask* curTask = current.first;
			std::set<Affinity> powerSet = AffinityTask::powerSet(curTask->affinity);
			Time currentResponse = responseTime.find(curTask)->second;
			TaskSet ignoreTask;
			ignoreTask.insert(curTask);

			Time min_sumInterfere = std::numeric_limits<Time>::max();
			for(Affinity s : powerSet)
			{
				assert(s.size() != 0);
				Size s_Size = s.size();
				//Time sumInterference = 0;
				std::unordered_map<CPUID, std::list<TaskSet>> possibleReplacement;
				for(auto cpu : s)
				{
					possibleReplacement.insert(std::pair<CPUID, std::list<TaskSet>>
							(cpu, std::list<TaskSet>()));
				}

				for(CPUID selectedCPU : s)
				{
					Affinity ignoreCPU(s);
					ignoreCPU.erase(selectedCPU);
					for(auto alternative : allCPU)
					{
						if(ignoreCPU.find(alternative) != ignoreCPU.end())
							continue;
						auto allPaths = allPath(taskSet, selectedCPU, alternative, ignoreCPU, ignoreTask);
						for(auto path : allPaths)
						{
							if(path.size() > 0)
							{
								TaskSet ignoredTask;
								Affinity moreCheck;
								for(auto item : path)
								{
									if(item.isTask())
										ignoredTask.insert(item.getTask());
									else
										moreCheck.insert(item.getCPUID());
								}
								TaskSet highTaskSet;
								for(AffinityTask* highPriorityTask : taskSet)
								{
									//if(compare(curTask, highPriorityTask))
									//	continue;
									if(highPriorityTask == curTask)
										continue;
									if(ignoredTask.find(highPriorityTask) != ignoredTask.end())
										continue;

									bool intersect = false;
									for(auto cpu : highPriorityTask->affinity)
									{
										if(moreCheck.find(cpu) != moreCheck.end())
										{
											intersect = true;
											break;
										}
									}
									if(!intersect)
										continue;

									highTaskSet.insert(highPriorityTask);
								}
								possibleReplacement.find(selectedCPU)->second.push_back(highTaskSet);
							}
						}
					}
				}


				for(auto possibleSet : combinePossibleTaskSet(possibleReplacement))
				{
					Time sumInterference = 0;
					/*
					if(possibleSet.size() ==0)
						continue;

					assert(possibleSet.size() > 0);
					*/
					sumInterference += overhead;
					for(auto highPriorityTask : possibleSet)
					{

						Time interferenceCount = currentResponse/highPriorityTask->minPeriod;
						Time remaining = currentResponse % highPriorityTask->minPeriod;
						Time interference = interferenceCount * highPriorityTask->worstExecution
								+ std::min(remaining, highPriorityTask->worstExecution);

						Time contextSwitchCount = interferenceCount;
						if(remaining > 0)
							contextSwitchCount++;

						sumInterference += 2*(contextSwitchCount) * overhead;

						if(compare(curTask, highPriorityTask))
							continue;

						sumInterference += interference;
					}


					Time floorValue = floor((Real)sumInterference / (Real)s_Size);

					min_sumInterfere = std::min(min_sumInterfere, floorValue);
				}
			}
			assert(min_sumInterfere != std::numeric_limits<Time>::max());

			Time nextResponse = curTask->worstExecution + min_sumInterfere;
			newResponseTime.insert(std::pair<AffinityTask*, Time>(curTask, nextResponse));
			if(currentResponse != nextResponse)
				changed = true;
			if(currentResponse > curTask->minPeriod)
				overflow = true;
		}

		if(changed)
			responseTime = newResponseTime;
		else
			break;
		if(overflow)
			break;
	}

	bool possible = true;
	for(auto iter : responseTime)
	{
		if(iter.second > iter.first->minPeriod)
		{
			possible = false;
			iter.first->print_log(WARN, "Execution time: %lu, Period: %lu, Response time: %lu",
					iter.first->worstExecution, iter.first->minPeriod, iter.second);
		}
		else
		{
			iter.first->print_log(INFO, "Execution time: %lu, Period: %lu, Response time: %lu",
					iter.first->worstExecution, iter.first->minPeriod, iter.second);
		}
	}

	return possible;
}
bool AffinityTask::staticWeakAnalysis(const TaskSet& taskSet, Time overhead)
{
	AffinityTask::Compare compare;
	std::unordered_map<AffinityTask*, Time> responseTime;
	for(AffinityTask* task : taskSet)
		responseTime.insert(std::pair<AffinityTask*, Time>(task, task->worstExecution));

	while(true)
	{
		bool changed = false;
		bool overflow = false;
		std::unordered_map<AffinityTask*, Time> newResponseTime;

		for(auto current : responseTime)
		{
			AffinityTask* curTask = current.first;
			std::set<Affinity> powerSet = AffinityTask::powerSet(curTask->affinity);
			Time currentResponse = responseTime.find(curTask)->second;

			Time min_sumInterfere = std::numeric_limits<Time>::max();
			for(Affinity s : powerSet)
			{
				assert(s.size() != 0);
				Size s_Size = s.size();
				Time sumInterference = 0;

				Time localSum = 0;
				TaskSet highPrioritySet;
				for(CPUID selectedCPU : s)
				{
					for(AffinityTask* highPriorityTask : taskSet)
					{
						if(compare(curTask, highPriorityTask))
							continue;
						if(highPriorityTask == curTask)
							continue;
						if(highPriorityTask->affinity.find(selectedCPU) == highPriorityTask->affinity.end())
							continue;

						highPrioritySet.insert(highPriorityTask);
					}
				}

				localSum += overhead;
				for(AffinityTask* highPriorityTask : highPrioritySet)
				{
					Time interferenceCount = currentResponse/highPriorityTask->minPeriod;
					Time remaining = currentResponse % highPriorityTask->minPeriod;
					Time interference = interferenceCount * highPriorityTask->worstExecution
							+ std::min(remaining, highPriorityTask->worstExecution);

					localSum += interference;
					Time contextSwitchCount = interferenceCount;
					if(remaining > 0)
						contextSwitchCount++;

					localSum += 2*(contextSwitchCount) * overhead;
				}

				sumInterference += localSum;


				Time floorValue = floor((Real)sumInterference / (Real)s_Size);

				min_sumInterfere = std::min(min_sumInterfere, floorValue);
			}
			assert(min_sumInterfere != std::numeric_limits<Time>::max());

			Time nextResponse = curTask->worstExecution + min_sumInterfere;
			newResponseTime.insert(std::pair<AffinityTask*, Time>(curTask, nextResponse));
			if(currentResponse != nextResponse)
				changed = true;
			if(currentResponse > curTask->minPeriod)
				overflow = true;
		}

		if(changed)
			responseTime = newResponseTime;
		else
			break;
		if(overflow)
			break;
	}

	bool possible = true;
	for(auto iter : responseTime)
	{
		if(iter.second > iter.first->minPeriod)
		{
			possible = false;
			iter.first->print_log(WARN, "Execution time: %lu, Period: %lu, Response time: %lu",
					iter.first->worstExecution, iter.first->minPeriod, iter.second);
		}
		else
		{
			iter.first->print_log(INFO, "Execution time: %lu, Period: %lu, Response time: %lu",
					iter.first->worstExecution, iter.first->minPeriod, iter.second);
		}
	}

	return possible;
}