scheduler.hh 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#ifndef __SYSTEMC_CORE_SCHEDULER_HH__ 3112953Sgabeblack@google.com#define __SYSTEMC_CORE_SCHEDULER_HH__ 3212953Sgabeblack@google.com 3312954Sgabeblack@google.com#include "sim/eventq.hh" 3412954Sgabeblack@google.com#include "systemc/core/channel.hh" 3512953Sgabeblack@google.com#include "systemc/core/list.hh" 3612953Sgabeblack@google.com#include "systemc/core/process.hh" 3712953Sgabeblack@google.com 3812953Sgabeblack@google.comnamespace sc_gem5 3912953Sgabeblack@google.com{ 4012953Sgabeblack@google.com 4112953Sgabeblack@google.comtypedef NodeList<Process> ProcessList; 4212954Sgabeblack@google.comtypedef NodeList<Channel> ChannelList; 4312954Sgabeblack@google.com 4412954Sgabeblack@google.com/* 4512954Sgabeblack@google.com * The scheduler supports three different mechanisms, the initialization phase, 4612954Sgabeblack@google.com * delta cycles, and timed notifications. 4712954Sgabeblack@google.com * 4812954Sgabeblack@google.com * INITIALIZATION PHASE 4912954Sgabeblack@google.com * 5012954Sgabeblack@google.com * The initialization phase has three parts: 5112954Sgabeblack@google.com * 1. Run requested channel updates. 5212954Sgabeblack@google.com * 2. Make processes which need to initialize runnable (methods and threads 5312954Sgabeblack@google.com * which didn't have dont_initialize called on them). 5412954Sgabeblack@google.com * 3. Process delta notifications. 5512954Sgabeblack@google.com * 5612954Sgabeblack@google.com * First, the Kernel SimObject calls the update() method during its startup() 5712954Sgabeblack@google.com * callback which handles the requested channel updates. The Kernel also 5812954Sgabeblack@google.com * schedules an event to be run at time 0 with a slightly elevated priority 5912954Sgabeblack@google.com * so that it happens before any "normal" event. 6012954Sgabeblack@google.com * 6112954Sgabeblack@google.com * When that t0 event happens, it calls the schedulers initToReady method 6212954Sgabeblack@google.com * which performs step 2 above. That indirectly causes the scheduler's 6312954Sgabeblack@google.com * readyEvent to be scheduled with slightly lowered priority, ensuring it 6412954Sgabeblack@google.com * happens after any "normal" event. 6512954Sgabeblack@google.com * 6612954Sgabeblack@google.com * Because delta notifications are scheduled at the standard priority, all 6712954Sgabeblack@google.com * of those events will happen next, performing step 3 above. Once they finish, 6812954Sgabeblack@google.com * if the readyEvent was scheduled above, there shouldn't be any higher 6912954Sgabeblack@google.com * priority events in front of it. When it runs, it will start the first 7012954Sgabeblack@google.com * evaluate phase of the first delta cycle. 7112954Sgabeblack@google.com * 7212954Sgabeblack@google.com * DELTA CYCLE 7312954Sgabeblack@google.com * 7412954Sgabeblack@google.com * A delta cycle has three phases within it. 7512954Sgabeblack@google.com * 1. The evaluate phase where runnable processes are allowed to run. 7612954Sgabeblack@google.com * 2. The update phase where requested channel updates hapen. 7712954Sgabeblack@google.com * 3. The delta notification phase where delta notifications happen. 7812954Sgabeblack@google.com * 7912954Sgabeblack@google.com * The readyEvent runs the first two steps of the delta cycle. It first goes 8012954Sgabeblack@google.com * through the list of runnable processes and executes them until the set is 8112954Sgabeblack@google.com * empty, and then immediately runs the update phase. Since these are all part 8212954Sgabeblack@google.com * of the same event, there's no chance for other events to intervene and 8312954Sgabeblack@google.com * break the required order above. 8412954Sgabeblack@google.com * 8512954Sgabeblack@google.com * During the update phase above, the spec forbids any action which would make 8612954Sgabeblack@google.com * a process runnable. That means that once the update phase finishes, the set 8712954Sgabeblack@google.com * of runnable processes will be empty. There may, however, have been some 8812954Sgabeblack@google.com * delta notifications/timeouts which will have been scheduled during either 8912954Sgabeblack@google.com * the evaluate or update phase above. Because those are scheduled at the 9012954Sgabeblack@google.com * normal priority, they will now happen together until there aren't any 9112954Sgabeblack@google.com * delta events left. 9212954Sgabeblack@google.com * 9312954Sgabeblack@google.com * If any processes became runnable during the delta notification phase, the 9412954Sgabeblack@google.com * readyEvent will have been scheduled and will have been waiting patiently 9512954Sgabeblack@google.com * behind the delta notification events. That will now run, effectively 9612954Sgabeblack@google.com * starting the next delta cycle. 9712954Sgabeblack@google.com * 9812954Sgabeblack@google.com * TIMED NOTIFICATION PHASE 9912954Sgabeblack@google.com * 10012954Sgabeblack@google.com * If no processes became runnable, the event queue will continue to process 10112954Sgabeblack@google.com * events until it comes across a timed notification, aka a notification 10212954Sgabeblack@google.com * scheduled to happen in the future. Like delta notification events, those 10312954Sgabeblack@google.com * will all happen together since the readyEvent priority is lower, 10412954Sgabeblack@google.com * potentially marking new processes as ready. Once these events finish, the 10512954Sgabeblack@google.com * readyEvent may run, starting the next delta cycle. 10612954Sgabeblack@google.com */ 10712953Sgabeblack@google.com 10812953Sgabeblack@google.comclass Scheduler 10912953Sgabeblack@google.com{ 11012953Sgabeblack@google.com public: 11112953Sgabeblack@google.com Scheduler(); 11212953Sgabeblack@google.com 11312954Sgabeblack@google.com const std::string name() const { return "systemc_scheduler"; } 11412954Sgabeblack@google.com 11512953Sgabeblack@google.com uint64_t numCycles() { return _numCycles; } 11612953Sgabeblack@google.com Process *current() { return _current; } 11712953Sgabeblack@google.com 11812954Sgabeblack@google.com // Mark processes that need to be initialized as ready. 11912954Sgabeblack@google.com void initToReady(); 12012953Sgabeblack@google.com 12112953Sgabeblack@google.com // Put a process on the list of processes to be initialized. 12212953Sgabeblack@google.com void init(Process *p) { initList.pushLast(p); } 12312953Sgabeblack@google.com 12412953Sgabeblack@google.com // Run the next process, if there is one. 12512953Sgabeblack@google.com void yield(); 12612953Sgabeblack@google.com 12712953Sgabeblack@google.com // Put a process on the ready list. 12812954Sgabeblack@google.com void ready(Process *p); 12912954Sgabeblack@google.com 13012954Sgabeblack@google.com // Schedule an update for a given channel. 13112954Sgabeblack@google.com void requestUpdate(Channel *c); 13212953Sgabeblack@google.com 13312953Sgabeblack@google.com // Run the given process immediately, preempting whatever may be running. 13412953Sgabeblack@google.com void 13512953Sgabeblack@google.com runNow(Process *p) 13612953Sgabeblack@google.com { 13712953Sgabeblack@google.com // If a process is running, schedule it/us to run again. 13812953Sgabeblack@google.com if (_current) 13912953Sgabeblack@google.com readyList.pushFirst(_current); 14012953Sgabeblack@google.com // Schedule p to run first. 14112953Sgabeblack@google.com readyList.pushFirst(p); 14212953Sgabeblack@google.com yield(); 14312953Sgabeblack@google.com } 14412953Sgabeblack@google.com 14512954Sgabeblack@google.com // Set an event queue for scheduling events. 14612954Sgabeblack@google.com void setEventQueue(EventQueue *_eq) { eq = _eq; } 14712954Sgabeblack@google.com 14812954Sgabeblack@google.com // Retrieve the event queue. 14912954Sgabeblack@google.com EventQueue &eventQueue() const { return *eq; } 15012954Sgabeblack@google.com 15112954Sgabeblack@google.com // Run scheduled channel updates. 15212954Sgabeblack@google.com void update(); 15312954Sgabeblack@google.com 15412953Sgabeblack@google.com private: 15512954Sgabeblack@google.com EventQueue *eq; 15612954Sgabeblack@google.com 15712954Sgabeblack@google.com void runReady(); 15812954Sgabeblack@google.com EventWrapper<Scheduler, &Scheduler::runReady> readyEvent; 15912954Sgabeblack@google.com void scheduleReadyEvent(); 16012954Sgabeblack@google.com 16112953Sgabeblack@google.com uint64_t _numCycles; 16212953Sgabeblack@google.com 16312953Sgabeblack@google.com Process *_current; 16412953Sgabeblack@google.com 16512953Sgabeblack@google.com ProcessList initList; 16612953Sgabeblack@google.com ProcessList readyList; 16712953Sgabeblack@google.com 16812954Sgabeblack@google.com ChannelList updateList; 16912953Sgabeblack@google.com}; 17012953Sgabeblack@google.com 17112953Sgabeblack@google.comextern Scheduler scheduler; 17212953Sgabeblack@google.com 17312953Sgabeblack@google.com} // namespace sc_gem5 17412953Sgabeblack@google.com 17512953Sgabeblack@google.com#endif // __SYSTEMC_CORE_SCHEDULER_H__ 176