?? scheduler.cc
字號:
//// Copyright (c) 2003 by Istv醤 V醨adi//// This file is part of dxr3Player, a DVD player written specifically // for the DXR3 (aka Hollywood+) decoder card.// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//------------------------------------------------------------------------------#include "Scheduler.h"#include "FDWaitCondition.h"#include "util/Util.h"#include "util/Log.h"#include "util/POSIX.h"#include <sys/time.h>#include <sys/times.h>//------------------------------------------------------------------------------using sched::Scheduler;using sched::Schedulable;using std::make_pair;//------------------------------------------------------------------------------Scheduler* Scheduler::instance = 0;//------------------------------------------------------------------------------Schedulable* Scheduler::currentSchedulable = 0;//------------------------------------------------------------------------------void Scheduler::initialize(size_t stackSize){ static Scheduler scheduler(stackSize); instance = &scheduler;}//------------------------------------------------------------------------------//------------------------------------------------------------------------------Scheduler::Scheduler(size_t stackSize) { char x; size_t stackTop = reinterpret_cast<size_t>(&x); stackTop -= stackSize; stackTop /= 4096; stackTop *= 4096; nextStackTop = reinterpret_cast<char*>(stackTop); struct tms tms; startClock = times(&tms);}//------------------------------------------------------------------------------void Scheduler::run(){ Log::debug("sched::Scheduler::run: %u schedulables\n", schedulables.size()); while(true) { runRunnables(); fd_set readFDs; FD_ZERO(&readFDs); fd_set writeFDs; FD_ZERO(&writeFDs); int maxFD = getFileDescriptors(readFDs, writeFDs); millis_t earliestTime = getEarliestTime(); struct timeval zero_tv = { tv_sec: 0, tv_usec: 0 }; struct timeval tv; struct timeval* tvPtr = 0; if (earliestTime==0) { tvPtr = &zero_tv; } else if (earliestTime!=INVALID_MILLIS) { millis_t currentTime = Util::currentTimeMillis(); millis_t diffTime = 0; if (earliestTime > (currentTime + 3) ) { diffTime = earliestTime - currentTime; } tv.tv_sec = diffTime / 1000; tv.tv_usec = (diffTime % 1000) * 1000; tvPtr = &tv; } int numDescriptors = 0; if (maxFD<0) { if (tvPtr==0) { break; } else if (tvPtr!=&zero_tv) { numDescriptors = POSIX::select(0, 0, 0, 0, tvPtr); } } else { numDescriptors = POSIX::select(maxFD+1, &readFDs, &writeFDs, 0, tvPtr); } setFileDescriptors(readFDs, writeFDs); setRunnability(); }}//------------------------------------------------------------------------------void Scheduler::printStatus(){ millis_t currentTime = Util::currentTimeMillis(); Log::debug("Scheduler with %u schedulables at %llu\n", schedulables.size(), currentTime); struct tms tms; long currentClock = times(&tms); long elapsedClock = currentClock - startClock; long userClock = tms.tms_utime; long sysClock = tms.tms_stime; Log::debug(" time elapsed (ticks): %ld, user: %ld (%5.2f %%), sys: %ld (%5.2f %%), total: %ld (%5.2f %%)\n", elapsedClock, userClock, double(userClock)*100.0/double(elapsedClock), sysClock, double(sysClock)*100.0/double(elapsedClock), userClock+sysClock, double(userClock + sysClock)*100.0/double(elapsedClock)); for(schedulables_t::const_iterator i = schedulables.begin(); i!=schedulables.end(); ++i) { const Schedulable* schedulable = (*i).first; Log::debug("Schedulable %s:\n", schedulable->name); const WaitCondition* cond = schedulable->waitCondition; if (cond!=0) { const char* interruptableClause = ""; if (schedulable->waitIsInterruptible) { interruptableClause = "interruptably "; } char timeoutClause[64] = { 0 }; millis_t timeout = schedulable->waitTimeout; if (timeout!=INVALID_MILLIS) { snprintf(timeoutClause, sizeof(timeoutClause), " with timeout %llu (%lld)", timeout, timeout - currentTime); } const char* interruptedClause = ""; if (schedulable->interruptPending) { interruptableClause = " An interrupt is pending."; } Log::debug(" is %swaiting on %s/%s (%sfulfilled)%s.%s\n", interruptableClause, cond->getOwnerName(), cond->getName(), cond->check() ? "" : "not ", timeoutClause, interruptedClause); } else { Log::debug(" is running\n"); } if ( (*i).second ) { Log::debug(" is runnable\n"); } schedulable->printStatus(); }}//------------------------------------------------------------------------------void Scheduler::quit() const{ for(schedulables_t::const_iterator i = schedulables.begin(); i!=schedulables.end(); ++i) { Schedulable* schedulable = (*i).first; schedulable->quit(); }}//------------------------------------------------------------------------------char* Scheduler::addSchedulable(Schedulable* schedulable, size_t stackSize){ schedulables.push_back(schedulableInfo_t(schedulable, true)); nextStackTop -= stackSize; return nextStackTop;}//------------------------------------------------------------------------------void Scheduler::addFDWaitCondition(FDWaitCondition* cond){ fdWaitConditions.insert(cond);}//------------------------------------------------------------------------------void Scheduler::removeFDWaitCondition(FDWaitCondition* cond){ fdWaitConditions.erase(cond);}//------------------------------------------------------------------------------millis_t Scheduler::getEarliestTime() const{ millis_t earliestTime = INVALID_MILLIS; for(schedulables_t::const_iterator i = schedulables.begin(); i!=schedulables.end() && earliestTime>0; ++i) { Schedulable* schedulable = (*i).first; if (schedulable->isRunnable()) { earliestTime = 0; } else { millis_t time = schedulable->waitTimeout; if (time<earliestTime) { earliestTime = time; } } } return earliestTime;}//------------------------------------------------------------------------------int Scheduler::getFileDescriptors(fd_set& readFDs, fd_set& writeFDs) const{ int maxFD = -1; for(fdWaitConditions_t::const_iterator i = fdWaitConditions.begin(); i!=fdWaitConditions.end(); ++i) { FDWaitCondition* cond = *i; if (!cond->hasWaiter()) continue; int fd = cond->getFileDescriptor(); if (fd<0) continue; fd_set& fdset = (cond->isReadable()) ? readFDs : writeFDs; FD_SET(fd, &fdset); if (fd>maxFD) maxFD = fd; } return maxFD;}//------------------------------------------------------------------------------void Scheduler::setFileDescriptors(const fd_set& readFDs, const fd_set& writeFDs) const{ for(fdWaitConditions_t::const_iterator i = fdWaitConditions.begin(); i!=fdWaitConditions.end(); ++i) { FDWaitCondition* cond = *i; if (!cond->hasWaiter()) continue; int fd = cond->getFileDescriptor(); if (fd<0) continue; const fd_set& fdset = (cond->isReadable()) ? readFDs : writeFDs; if (FD_ISSET(fd, &fdset)) { cond->set(); } }}//------------------------------------------------------------------------------void Scheduler::setRunnability(){ millis_t currentTime = Util::currentTimeMillis(); for(schedulables_t::iterator i = schedulables.begin(); i!=schedulables.end(); ++i) { schedulableInfo_t& schedulableInfo = *i; schedulableInfo.second = schedulableInfo.first->isRunnable(currentTime); }}//------------------------------------------------------------------------------void Scheduler::runRunnables(){ for(schedulables_t::const_iterator i = schedulables.begin(); i!=schedulables.end(); ++i) { const schedulableInfo_t& schedulableInfo = *i; if (schedulableInfo.second) { runSchedulable(schedulableInfo.first); } }}//------------------------------------------------------------------------------void Scheduler::runSchedulable(Schedulable* schedulable){ if (setjmp(state)==0) { currentSchedulable = schedulable; schedulable->resume(); } else { currentSchedulable = 0; }}//------------------------------------------------------------------------------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -