/** * \details Remove all jobs whose deadline is in the past and check that they were completed successfully. * \return true if all jobs whose deadline is in the past are completed successfully, false otherwise. */ bool Simulation::cleanAndCheckJobs(int t) { if (_jobs.empty()) return true; // save CPUs deque<Job> savedCPUs(_CPUs.size()); for (unsigned int i = 0; i < _CPUs.size(); ++i) { if (_CPUs[i] != NULL) { savedCPUs[i] = (*_CPUs[i]); } } for (deque<Job>::iterator it = _jobs.begin(); it != _jobs.end() and not _jobs.empty(); it++) { if (it->getAbsoluteDeadline() < t) { if (it->getComputationLeft() != 0) { return false; } else { assert(findInDeque((*it), savedCPUs) == -1); it = _jobs.erase(it); } } if (it == _jobs.end()) break; } // restore CPU for (unsigned int i = 0; i < _CPUs.size(); ++i) { if (savedCPUs[i].getStartTime() != -1) { int posJob = findInDeque<Job>(savedCPUs[i], _jobs); assert(posJob != -1); _CPUs[i] = &_jobs[posJob]; } } return true; }
/** * \details Run global EDF (adapted to "pure" global EDF and to EDF-k). * \return A vector containing the statistics of the system * vector[0]= average number of preemption * vector[1]= average number of migration * vector[2]= average idle time * vector[3]= number_of_core_necessary * vector[4]= studyInterval */ vector<int> Simulation::runGlobal() { long studyInterval = computeStudyInterval(); bool isSchedulable = true; _jobs.clear(); _t = 0; while (_t < studyInterval && isSchedulable) // main loop { if (DEBUG) { cout << endl << "t: " << _t << endl; cout << "initial CPUs" << endl; for (unsigned int i = 0; i < _CPUs.size(); ++i) { cout << "\tCPU[" << i << "]: "; if (_CPUs[i] != NULL) cout << _CPUs[i]->asString(); cout << endl; } } generateNewJobs(_t); _readyJobs = getReadyJobs(); _runningJobs = getRunningJobs(); int firstIdleCPU = positionOfFirstIdleCPU(); bool availableCPUs = (firstIdleCPU != -1); // scheduling : assign which jobs goes to which CPUs while (not _readyJobs.empty() and (availableCPUs or JobNeedToBePreempted() )) { // If we get in this loop, we know that the earliest-deadline active job should get a CPU assert(_readyJobs.top()->getComputationLeft() > 0); if (availableCPUs) { assert(_CPUs[firstIdleCPU] == NULL); Job* newJob = _readyJobs.top(); _readyJobs.pop(); _CPUs[firstIdleCPU] = newJob; _runningJobs.push(newJob); if (DEBUG) cout << "hi to\t" << newJob->asString() << "\tat CPU " << firstIdleCPU << endl; } else // all CPUs are busy, preempt the one with the latest deadline { Job* oldJob = _runningJobs.top(); _runningJobs.pop(); Job* newJob = _readyJobs.top(); _readyJobs.pop(); int posOldJob = findInDeque<Job*>(oldJob, _CPUs); assert (posOldJob != -1); _CPUs[posOldJob] = newJob; _readyJobs.push(oldJob); _runningJobs.push(newJob); preemption_counter++; if (DEBUG) cout << "bye to\t" << oldJob->asString() << "\tat CPU " << firstIdleCPU << endl; if (DEBUG) cout << "hi to\t" << newJob->asString() << "\tat CPU " << firstIdleCPU << endl; } _readyJobs = getReadyJobs(); _runningJobs = getRunningJobs(); firstIdleCPU = positionOfFirstIdleCPU(); availableCPUs = (firstIdleCPU != -1); } // CPUs if (DEBUG) cout << "CPUS" << endl; int idle_cpus_count = 0; for (unsigned int i = 0; i < _CPUs.size(); ++i) { if (DEBUG) cout << "\tCPU[" << i << "]: "; if (_CPUs[i] != NULL) { if (DEBUG) cout << _CPUs[i]->asString(); // verifications assert(findInDeque(_CPUs[i], _CPUs) == (int)i); assert(_CPUs[i]->getComputationLeft() > 0); // compute jobs in CPUs if (_CPUs[i]->getLastCPU_Id() != -1 and _CPUs[i]->getLastCPU_Id() != (int) i) ++migration_counter; _CPUs[i]->giveCPU(_deltaT, i); // check if a job is done if (_CPUs[i]->getComputationLeft() == 0) { if (DEBUG) cout << "\tbye!"; _CPUs[i] = NULL; } } else { ++idle_cpus_count; ++idle_time_counter; } if (DEBUG) cout << endl; } if ((int)_CPUs.size() - idle_cpus_count > number_of_core_necessary) { number_of_core_necessary = _CPUs.size() - idle_cpus_count; } // advance time _t += _deltaT; isSchedulable = cleanAndCheckJobs(_t); } vector<int> result; if(isSchedulable) { result.push_back(preemption_counter); result.push_back(migration_counter); result.push_back(idle_time_counter); result.push_back(number_of_core_necessary); result.push_back(studyInterval); } return result; }
void ScutCxListItem::MyTouchDispatcher(CCNode* pParent, int nToutchEvent, CCTouch* touch, CCEvent* event) { CCNode* parent = pParent; while(parent) { //对嵌套列表TOUCH END 做事件传递 //if (parent->getClassType() == ScutLIST_classID && nToutchEvent == TOUCHEND) // break; if(findInDeque(pParent)) { if(nToutchEvent == TOUCHEND) break; } CCPoint pos_parent = parent->getPosition(); CCPoint pos_in_parent = parent->convertTouchToNodeSpace(touch); CCSize size_parent = parent->getContentSize(); ////对横屏例表作特殊处理 if(pos_parent.x < 0) pos_in_parent.x = pos_in_parent.x + pos_parent.x; CCRect r; r.origin = CCPointZero; r.size = size_parent; if (!r.containsPoint(pos_in_parent)) { if(pos_parent.y > 0) { //对竖屏例表作特殊处理 pos_in_parent.y = pos_in_parent.y + pos_parent.y; if (!r.containsPoint(pos_in_parent)) { return; } } else { return; } } parent = parent->getParent(); } switch(nToutchEvent) { case TOUCHBEGIN: { if(dynamic_cast<CCLayer*>(pParent) != NULL) { bool bCatch = ((CCLayer*)pParent)->ccTouchBegan(touch,event); if(bCatch && findInTouchEventLayerDeque(pParent) ) { m_pVectorTouchBegan.push_back((CCLayer*)pParent); m_bCatchEndNode = true; g_bCatchLayer = true; } } if (pParent && pParent->getChildren()) { CCNode* pItem = NULL; for (int i = 0, l = pParent->getChildren()->count(); i < l; ++i) { pItem = (CCNode *)pParent->getChildren()->objectAtIndex(i); if(pItem) { MyTouchDispatcher(pItem, nToutchEvent,touch,event); } } } } break; case TOUCHEND: { if(dynamic_cast<CCLayer*>(pParent) != NULL) ((CCLayer*)pParent)->ccTouchEnded(touch,event); if (pParent && pParent->getChildren()) { CCNode* pItem = NULL; for (int i = 0, l = pParent->getChildren()->count(); i < l; ++i) { pItem = (CCNode *)pParent->getChildren()->objectAtIndex(i); if(pItem) { MyTouchDispatcher(pItem, nToutchEvent,touch,event); } } } } break; case TOUCHMOVING: { if(dynamic_cast<CCLayer*>(pParent) != NULL) ((CCLayer*)pParent)->ccTouchMoved(touch,event); if (pParent && pParent->getChildren()) { CCNode* pItem = NULL; for (int i = 0, l = pParent->getChildren()->count(); i < l; ++i) { pItem = (CCNode *)pParent->getChildren()->objectAtIndex(i); if(pItem) { MyTouchDispatcher(pItem, nToutchEvent,touch,event); } } } } break; case TOUCHCANCELLED: { if(dynamic_cast<CCLayer*>(pParent) != NULL) ((CCLayer*)pParent)->ccTouchCancelled(touch,event); if (pParent && pParent->getChildren()) { CCNode* pItem = NULL; for (int i = 0, l = pParent->getChildren()->count(); i < l; ++i) { pItem = (CCNode *)pParent->getChildren()->objectAtIndex(i); if(pItem) { MyTouchDispatcher(pItem, nToutchEvent,touch,event); } } } } break; default: break; } }