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); } } }
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; }