scheduler.cc revision 12954
112953Sgabeblack@google.com/* 212953Sgabeblack@google.com * Copyright 2018 Google, Inc. 312953Sgabeblack@google.com * 412953Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without 512953Sgabeblack@google.com * modification, are permitted provided that the following conditions are 612953Sgabeblack@google.com * met: redistributions of source code must retain the above copyright 712953Sgabeblack@google.com * notice, this list of conditions and the following disclaimer; 812953Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright 912953Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the 1012953Sgabeblack@google.com * documentation and/or other materials provided with the distribution; 1112953Sgabeblack@google.com * neither the name of the copyright holders nor the names of its 1212953Sgabeblack@google.com * contributors may be used to endorse or promote products derived from 1312953Sgabeblack@google.com * this software without specific prior written permission. 1412953Sgabeblack@google.com * 1512953Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1612953Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1712953Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1812953Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1912953Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2012953Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 2112953Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2212953Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2312953Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2412953Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2512953Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2612953Sgabeblack@google.com * 2712953Sgabeblack@google.com * Authors: Gabe Black 2812953Sgabeblack@google.com */ 2912953Sgabeblack@google.com 3012953Sgabeblack@google.com#include "systemc/core/scheduler.hh" 3112953Sgabeblack@google.com 3212953Sgabeblack@google.com#include "base/fiber.hh" 3312954Sgabeblack@google.com#include "base/logging.hh" 3412954Sgabeblack@google.com#include "sim/eventq.hh" 3512953Sgabeblack@google.com 3612953Sgabeblack@google.comnamespace sc_gem5 3712953Sgabeblack@google.com{ 3812953Sgabeblack@google.com 3912954Sgabeblack@google.comScheduler::Scheduler() : 4012954Sgabeblack@google.com eq(nullptr), readyEvent(this, false, EventBase::Default_Pri + 1), 4112954Sgabeblack@google.com _numCycles(0), _current(nullptr) 4212954Sgabeblack@google.com{} 4312953Sgabeblack@google.com 4412953Sgabeblack@google.comvoid 4512954Sgabeblack@google.comScheduler::initToReady() 4612953Sgabeblack@google.com{ 4712953Sgabeblack@google.com while (!initList.empty()) 4812953Sgabeblack@google.com ready(initList.getNext()); 4912953Sgabeblack@google.com} 5012953Sgabeblack@google.com 5112953Sgabeblack@google.comvoid 5212953Sgabeblack@google.comScheduler::yield() 5312953Sgabeblack@google.com{ 5412953Sgabeblack@google.com _current = readyList.getNext(); 5512953Sgabeblack@google.com if (!_current) { 5612953Sgabeblack@google.com // There are no more processes, so return control to evaluate. 5712953Sgabeblack@google.com Fiber::primaryFiber()->run(); 5812953Sgabeblack@google.com } else { 5912953Sgabeblack@google.com _current->popListNode(); 6012953Sgabeblack@google.com // Switch to whatever Fiber is supposed to run this process. All 6112953Sgabeblack@google.com // Fibers which aren't running should be parked at this line. 6212953Sgabeblack@google.com _current->fiber()->run(); 6312953Sgabeblack@google.com // If the current process hasn't been started yet, start it. This 6412953Sgabeblack@google.com // should always be true for methods, but may not be true for threads. 6512953Sgabeblack@google.com if (_current && !_current->running()) 6612953Sgabeblack@google.com _current->run(); 6712953Sgabeblack@google.com } 6812953Sgabeblack@google.com} 6912953Sgabeblack@google.com 7012953Sgabeblack@google.comvoid 7112954Sgabeblack@google.comScheduler::ready(Process *p) 7212953Sgabeblack@google.com{ 7312954Sgabeblack@google.com // Clump methods together to minimize context switching. 7412954Sgabeblack@google.com if (p->procKind() == ::sc_core::SC_METHOD_PROC_) 7512954Sgabeblack@google.com readyList.pushFirst(p); 7612954Sgabeblack@google.com else 7712954Sgabeblack@google.com readyList.pushLast(p); 7812953Sgabeblack@google.com 7912954Sgabeblack@google.com scheduleReadyEvent(); 8012954Sgabeblack@google.com} 8112954Sgabeblack@google.com 8212954Sgabeblack@google.comvoid 8312954Sgabeblack@google.comScheduler::requestUpdate(Channel *c) 8412954Sgabeblack@google.com{ 8512954Sgabeblack@google.com updateList.pushLast(c); 8612954Sgabeblack@google.com scheduleReadyEvent(); 8712954Sgabeblack@google.com} 8812954Sgabeblack@google.com 8912954Sgabeblack@google.comvoid 9012954Sgabeblack@google.comScheduler::scheduleReadyEvent() 9112954Sgabeblack@google.com{ 9212954Sgabeblack@google.com // Schedule the evaluate and update phases. 9312954Sgabeblack@google.com if (!readyEvent.scheduled()) { 9412954Sgabeblack@google.com panic_if(!eq, "Need to schedule ready, but no event manager.\n"); 9512954Sgabeblack@google.com eq->schedule(&readyEvent, eq->getCurTick()); 9612954Sgabeblack@google.com } 9712954Sgabeblack@google.com} 9812954Sgabeblack@google.com 9912954Sgabeblack@google.comvoid 10012954Sgabeblack@google.comScheduler::runReady() 10112954Sgabeblack@google.com{ 10212954Sgabeblack@google.com bool empty = readyList.empty(); 10312954Sgabeblack@google.com 10412954Sgabeblack@google.com // The evaluation phase. 10512953Sgabeblack@google.com do { 10612953Sgabeblack@google.com yield(); 10712953Sgabeblack@google.com } while (!readyList.empty()); 10812954Sgabeblack@google.com 10912954Sgabeblack@google.com if (!empty) 11012954Sgabeblack@google.com _numCycles++; 11112954Sgabeblack@google.com 11212954Sgabeblack@google.com // The update phase. 11312954Sgabeblack@google.com update(); 11412954Sgabeblack@google.com 11512954Sgabeblack@google.com // The delta phase will happen naturally through the event queue. 11612953Sgabeblack@google.com} 11712953Sgabeblack@google.com 11812953Sgabeblack@google.comvoid 11912953Sgabeblack@google.comScheduler::update() 12012953Sgabeblack@google.com{ 12112954Sgabeblack@google.com Channel *channel = updateList.getNext(); 12212954Sgabeblack@google.com while (channel) { 12312954Sgabeblack@google.com channel->popListNode(); 12412954Sgabeblack@google.com channel->update(); 12512954Sgabeblack@google.com channel = updateList.getNext(); 12612954Sgabeblack@google.com } 12712953Sgabeblack@google.com} 12812953Sgabeblack@google.com 12912953Sgabeblack@google.comScheduler scheduler; 13012953Sgabeblack@google.com 13112953Sgabeblack@google.com} // namespace sc_gem5 132