scheduler.cc revision 12987
18926Sandreas.hansson@arm.com/* 27586SAli.Saidi@arm.com * Copyright 2018 Google, Inc. 37586SAli.Saidi@arm.com * 47586SAli.Saidi@arm.com * Redistribution and use in source and binary forms, with or without 57586SAli.Saidi@arm.com * modification, are permitted provided that the following conditions are 67586SAli.Saidi@arm.com * met: redistributions of source code must retain the above copyright 77586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer; 87586SAli.Saidi@arm.com * redistributions in binary form must reproduce the above copyright 97586SAli.Saidi@arm.com * notice, this list of conditions and the following disclaimer in the 107586SAli.Saidi@arm.com * documentation and/or other materials provided with the distribution; 117586SAli.Saidi@arm.com * neither the name of the copyright holders nor the names of its 127586SAli.Saidi@arm.com * contributors may be used to endorse or promote products derived from 133970Sgblack@eecs.umich.edu * this software without specific prior written permission. 143005Sstever@eecs.umich.edu * 153005Sstever@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 163005Sstever@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 173005Sstever@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 183005Sstever@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 193005Sstever@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 203005Sstever@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 213005Sstever@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 223005Sstever@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 233005Sstever@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 243005Sstever@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 253005Sstever@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 263005Sstever@eecs.umich.edu * 273005Sstever@eecs.umich.edu * Authors: Gabe Black 283005Sstever@eecs.umich.edu */ 293005Sstever@eecs.umich.edu 303005Sstever@eecs.umich.edu#include "systemc/core/scheduler.hh" 313005Sstever@eecs.umich.edu 323005Sstever@eecs.umich.edu#include "base/fiber.hh" 333005Sstever@eecs.umich.edu#include "base/logging.hh" 343005Sstever@eecs.umich.edu#include "sim/eventq.hh" 353005Sstever@eecs.umich.edu#include "systemc/core/kernel.hh" 363005Sstever@eecs.umich.edu#include "systemc/ext/core/sc_main.hh" 373005Sstever@eecs.umich.edu 383005Sstever@eecs.umich.edunamespace sc_gem5 393005Sstever@eecs.umich.edu{ 403005Sstever@eecs.umich.edu 416654Snate@binkert.orgScheduler::Scheduler() : 426654Snate@binkert.org eq(nullptr), readyEvent(this, false, ReadyPriority), 432889SN/A pauseEvent(this, false, PausePriority), 442710SN/A stopEvent(this, false, StopPriority), 456654Snate@binkert.org scMain(nullptr), 466654Snate@binkert.org starvationEvent(this, false, StarvationPriority), 476654Snate@binkert.org _started(false), _paused(false), _stopped(false), 485457Ssaidi@eecs.umich.edu maxTickEvent(this, false, MaxTickPriority), 496654Snate@binkert.org _numCycles(0), _current(nullptr), initReady(false) 506654Snate@binkert.org{} 512934SN/A 522549SN/Avoid 532995SN/AScheduler::prepareForInit() 543395Shsul@eecs.umich.edu{ 556981SLisa.Hsu@amd.com for (Process *p = toFinalize.getNext(); p; p = toFinalize.getNext()) { 563448Shsul@eecs.umich.edu p->finalize(); 578920Snilay@cs.wisc.edu p->popListNode(); 583444Sktlim@umich.edu } 592889SN/A 608920Snilay@cs.wisc.edu for (Process *p = initList.getNext(); p; p = initList.getNext()) { 618920Snilay@cs.wisc.edu p->finalize(); 623322Shsul@eecs.umich.edu p->ready(); 632710SN/A } 642710SN/A 652710SN/A for (auto ets: eventsToSchedule) 662710SN/A eq->schedule(ets.first, ets.second); 672710SN/A eventsToSchedule.clear(); 682710SN/A 693322Shsul@eecs.umich.edu if (_started) 703304Sstever@eecs.umich.edu eq->schedule(&maxTickEvent, maxTick); 713322Shsul@eecs.umich.edu 723322Shsul@eecs.umich.edu initReady = true; 733304Sstever@eecs.umich.edu} 743481Shsul@eecs.umich.edu 753481Shsul@eecs.umich.eduvoid 762566SN/AScheduler::reg(Process *p) 779129Sandreas.hansson@arm.com{ 789129Sandreas.hansson@arm.com if (initReady) { 792995SN/A // If we're past initialization, finalize static sensitivity. 802995SN/A p->finalize(); 813304Sstever@eecs.umich.edu // Mark the process as ready. 823304Sstever@eecs.umich.edu p->ready(); 833304Sstever@eecs.umich.edu } else { 842995SN/A // Otherwise, record that this process should be initialized once we 852995SN/A // get there. 862995SN/A initList.pushLast(p); 872917SN/A } 882995SN/A} 898956Sjayneel@cs.wisc.edu 902995SN/Avoid 918956Sjayneel@cs.wisc.eduScheduler::dontInitialize(Process *p) 923304Sstever@eecs.umich.edu{ 936135Sgblack@eecs.umich.edu if (initReady) { 946135Sgblack@eecs.umich.edu // Pop this process off of the ready list. 956654Snate@binkert.org p->popListNode(); 963819Shsul@eecs.umich.edu } else { 976654Snate@binkert.org // Push this process onto the list of processes which still need 985222Sksewell@umich.edu // their static sensitivity to be finalized. That implicitly pops it 996654Snate@binkert.org // off the list of processes to be initialized/marked ready. 1003819Shsul@eecs.umich.edu toFinalize.pushLast(p); 1016654Snate@binkert.org } 1027925Sgblack@eecs.umich.edu} 1037586SAli.Saidi@arm.com 1048061SAli.Saidi@ARM.comvoid 1058061SAli.Saidi@ARM.comScheduler::yield() 1068061SAli.Saidi@ARM.com{ 1073819Shsul@eecs.umich.edu _current = readyList.getNext(); 1089059Snilay@cs.wisc.edu if (!_current) { 1093819Shsul@eecs.umich.edu // There are no more processes, so return control to evaluate. 1103873Sbinkertn@umich.edu Fiber::primaryFiber()->run(); 1113873Sbinkertn@umich.edu } else { 1123873Sbinkertn@umich.edu _current->popListNode(); 1133873Sbinkertn@umich.edu // Switch to whatever Fiber is supposed to run this process. All 1143873Sbinkertn@umich.edu // Fibers which aren't running should be parked at this line. 1153873Sbinkertn@umich.edu _current->fiber()->run(); 1168659SAli.Saidi@ARM.com // If the current process needs to be manually started, start it. 1178659SAli.Saidi@ARM.com if (_current && _current->needsStart()) 1186995Sgblack@eecs.umich.edu _current->run(); 1193668Srdreslin@umich.edu } 1208713Sandreas.hansson@arm.com} 1218713Sandreas.hansson@arm.com 1228713Sandreas.hansson@arm.comvoid 1238713Sandreas.hansson@arm.comScheduler::ready(Process *p) 1246636Ssteve.reinhardt@amd.com{ 1258894Ssaidi@eecs.umich.edu // Clump methods together to minimize context switching. 1268839Sandreas.hansson@arm.com if (p->procKind() == ::sc_core::SC_METHOD_PROC_) 1278839Sandreas.hansson@arm.com readyList.pushFirst(p); 1288713Sandreas.hansson@arm.com else 1298713Sandreas.hansson@arm.com readyList.pushLast(p); 1308870SAli.Saidi@ARM.com 1318839Sandreas.hansson@arm.com scheduleReadyEvent(); 1328839Sandreas.hansson@arm.com} 1335142Ssaidi@eecs.umich.edu 1348926Sandreas.hansson@arm.comvoid 1358926Sandreas.hansson@arm.comScheduler::requestUpdate(Channel *c) 1368926Sandreas.hansson@arm.com{ 1378926Sandreas.hansson@arm.com updateList.pushLast(c); 1383312Sstever@eecs.umich.edu scheduleReadyEvent(); 1394968Sacolyte@umich.edu} 1408926Sandreas.hansson@arm.com 1418887Sgeoffrey.blake@arm.comvoid 1428887Sgeoffrey.blake@arm.comScheduler::scheduleReadyEvent() 1438887Sgeoffrey.blake@arm.com{ 1448887Sgeoffrey.blake@arm.com // Schedule the evaluate and update phases. 1454968Sacolyte@umich.edu if (!readyEvent.scheduled()) { 1463005Sstever@eecs.umich.edu panic_if(!eq, "Need to schedule ready, but no event manager.\n"); 1476654Snate@binkert.org eq->schedule(&readyEvent, eq->getCurTick()); 1483819Shsul@eecs.umich.edu if (starvationEvent.scheduled()) 1496654Snate@binkert.org eq->deschedule(&starvationEvent); 1505222Sksewell@umich.edu } 1516654Snate@binkert.org} 1523819Shsul@eecs.umich.edu 1536654Snate@binkert.orgvoid 1546135Sgblack@eecs.umich.eduScheduler::scheduleStarvationEvent() 1557586SAli.Saidi@arm.com{ 1568661SAli.Saidi@ARM.com if (!starvationEvent.scheduled()) { 1578661SAli.Saidi@ARM.com panic_if(!eq, "Need to schedule starvation event, " 1583322Shsul@eecs.umich.edu "but no event manager.\n"); 1598863Snilay@cs.wisc.edu eq->schedule(&starvationEvent, eq->getCurTick()); 1607876Sgblack@eecs.umich.edu if (readyEvent.scheduled()) 1614968Sacolyte@umich.edu eq->deschedule(&readyEvent); 1628926Sandreas.hansson@arm.com } 1634837Ssaidi@eecs.umich.edu} 1644837Ssaidi@eecs.umich.edu 1658810SAli.Saidi@ARM.comvoid 1668870SAli.Saidi@ARM.comScheduler::runReady() 1678845Sandreas.hansson@arm.com{ 1688845Sandreas.hansson@arm.com bool empty = readyList.empty(); 1694837Ssaidi@eecs.umich.edu 1708659SAli.Saidi@ARM.com // The evaluation phase. 1718801Sgblack@eecs.umich.edu do { 1723005Sstever@eecs.umich.edu yield(); 1738801Sgblack@eecs.umich.edu } while (!readyList.empty()); 1743005Sstever@eecs.umich.edu 1753005Sstever@eecs.umich.edu if (!empty) 1763005Sstever@eecs.umich.edu _numCycles++; 1772566SN/A 1787861Sgblack@eecs.umich.edu // The update phase. 1797861Sgblack@eecs.umich.edu update(); 1807861Sgblack@eecs.umich.edu 1818635Schris.emmons@arm.com if (starved() && !runToTime) 1828635Schris.emmons@arm.com scheduleStarvationEvent(); 1838635Schris.emmons@arm.com 1849061Snilay@cs.wisc.edu // The delta phase will happen naturally through the event queue. 1853481Shsul@eecs.umich.edu} 186 187void 188Scheduler::update() 189{ 190 Channel *channel = updateList.getNext(); 191 while (channel) { 192 channel->popListNode(); 193 channel->update(); 194 channel = updateList.getNext(); 195 } 196} 197 198void 199Scheduler::pause() 200{ 201 _paused = true; 202 kernel->status(::sc_core::SC_PAUSED); 203 scMain->run(); 204} 205 206void 207Scheduler::stop() 208{ 209 _stopped = true; 210 kernel->stop(); 211 scMain->run(); 212} 213 214void 215Scheduler::start(Tick max_tick, bool run_to_time) 216{ 217 // We should be running from sc_main. Keep track of that Fiber to return 218 // to later. 219 scMain = Fiber::currentFiber(); 220 221 _started = true; 222 _paused = false; 223 _stopped = false; 224 runToTime = run_to_time; 225 226 maxTick = max_tick; 227 228 if (starved() && !runToTime) 229 return; 230 231 if (initReady) { 232 kernel->status(::sc_core::SC_RUNNING); 233 eq->schedule(&maxTickEvent, maxTick); 234 } 235 236 // Return to gem5 to let it run events, etc. 237 Fiber::primaryFiber()->run(); 238 239 if (pauseEvent.scheduled()) 240 eq->deschedule(&pauseEvent); 241 if (stopEvent.scheduled()) 242 eq->deschedule(&stopEvent); 243 if (maxTickEvent.scheduled()) 244 eq->deschedule(&maxTickEvent); 245 if (starvationEvent.scheduled()) 246 eq->deschedule(&starvationEvent); 247} 248 249void 250Scheduler::schedulePause() 251{ 252 if (pauseEvent.scheduled()) 253 return; 254 255 eq->schedule(&pauseEvent, eq->getCurTick()); 256} 257 258void 259Scheduler::scheduleStop(bool finish_delta) 260{ 261 if (stopEvent.scheduled()) 262 return; 263 264 if (!finish_delta) { 265 // If we're not supposed to finish the delta cycle, flush the list 266 // of ready processes and scheduled updates. 267 Process *p; 268 while ((p = readyList.getNext())) 269 p->popListNode(); 270 Channel *c; 271 while ((c = updateList.getNext())) 272 c->popListNode(); 273 } 274 eq->schedule(&stopEvent, eq->getCurTick()); 275} 276 277Scheduler scheduler; 278 279} // namespace sc_gem5 280