32a33,34
> #include "sim/eventq.hh"
> #include "systemc/core/channel.hh"
39a42
> typedef NodeList<Channel> ChannelList;
40a44,107
> /*
> * The scheduler supports three different mechanisms, the initialization phase,
> * delta cycles, and timed notifications.
> *
> * INITIALIZATION PHASE
> *
> * The initialization phase has three parts:
> * 1. Run requested channel updates.
> * 2. Make processes which need to initialize runnable (methods and threads
> * which didn't have dont_initialize called on them).
> * 3. Process delta notifications.
> *
> * First, the Kernel SimObject calls the update() method during its startup()
> * callback which handles the requested channel updates. The Kernel also
> * schedules an event to be run at time 0 with a slightly elevated priority
> * so that it happens before any "normal" event.
> *
> * When that t0 event happens, it calls the schedulers initToReady method
> * which performs step 2 above. That indirectly causes the scheduler's
> * readyEvent to be scheduled with slightly lowered priority, ensuring it
> * happens after any "normal" event.
> *
> * Because delta notifications are scheduled at the standard priority, all
> * of those events will happen next, performing step 3 above. Once they finish,
> * if the readyEvent was scheduled above, there shouldn't be any higher
> * priority events in front of it. When it runs, it will start the first
> * evaluate phase of the first delta cycle.
> *
> * DELTA CYCLE
> *
> * A delta cycle has three phases within it.
> * 1. The evaluate phase where runnable processes are allowed to run.
> * 2. The update phase where requested channel updates hapen.
> * 3. The delta notification phase where delta notifications happen.
> *
> * The readyEvent runs the first two steps of the delta cycle. It first goes
> * through the list of runnable processes and executes them until the set is
> * empty, and then immediately runs the update phase. Since these are all part
> * of the same event, there's no chance for other events to intervene and
> * break the required order above.
> *
> * During the update phase above, the spec forbids any action which would make
> * a process runnable. That means that once the update phase finishes, the set
> * of runnable processes will be empty. There may, however, have been some
> * delta notifications/timeouts which will have been scheduled during either
> * the evaluate or update phase above. Because those are scheduled at the
> * normal priority, they will now happen together until there aren't any
> * delta events left.
> *
> * If any processes became runnable during the delta notification phase, the
> * readyEvent will have been scheduled and will have been waiting patiently
> * behind the delta notification events. That will now run, effectively
> * starting the next delta cycle.
> *
> * TIMED NOTIFICATION PHASE
> *
> * If no processes became runnable, the event queue will continue to process
> * events until it comes across a timed notification, aka a notification
> * scheduled to happen in the future. Like delta notification events, those
> * will all happen together since the readyEvent priority is lower,
> * potentially marking new processes as ready. Once these events finish, the
> * readyEvent may run, starting the next delta cycle.
> */
>
45a113,114
> const std::string name() const { return "systemc_scheduler"; }
>
49,50c118,119
< // Run the initialization phase.
< void initialize();
---
> // Mark processes that need to be initialized as ready.
> void initToReady();
52,54d120
< // Run delta cycles until time needs to advance.
< void runCycles();
<
62,70c128
< void
< ready(Process *p)
< {
< // Clump methods together to minimize context switching.
< if (p->procKind() == ::sc_core::SC_METHOD_PROC_)
< readyList.pushFirst(p);
< else
< readyList.pushLast(p);
< }
---
> void ready(Process *p);
71a130,132
> // Schedule an update for a given channel.
> void requestUpdate(Channel *c);
>
83a145,153
> // Set an event queue for scheduling events.
> void setEventQueue(EventQueue *_eq) { eq = _eq; }
>
> // Retrieve the event queue.
> EventQueue &eventQueue() const { return *eq; }
>
> // Run scheduled channel updates.
> void update();
>
84a155,160
> EventQueue *eq;
>
> void runReady();
> EventWrapper<Scheduler, &Scheduler::runReady> readyEvent;
> void scheduleReadyEvent();
>
92,94c168
< void evaluate();
< void update();
< void delta();
---
> ChannelList updateList;