eventq.cc revision 224
112855Sgabeblack@google.com/*
212855Sgabeblack@google.com * Copyright (c) 2003 The Regents of The University of Michigan
312855Sgabeblack@google.com * All rights reserved.
412855Sgabeblack@google.com *
512855Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612855Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712855Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912855Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012855Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112855Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212855Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312855Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412855Sgabeblack@google.com * this software without specific prior written permission.
1512855Sgabeblack@google.com *
1612855Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712855Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812855Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912855Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012855Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112855Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212855Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312855Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412855Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512855Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612855Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712855Sgabeblack@google.com */
2812855Sgabeblack@google.com
2912855Sgabeblack@google.com#include <assert.h>
3012855Sgabeblack@google.com
3112855Sgabeblack@google.com#include <iostream>
3212855Sgabeblack@google.com#include <string>
3312855Sgabeblack@google.com#include <sstream>
3412855Sgabeblack@google.com#include <vector>
3512855Sgabeblack@google.com
3612855Sgabeblack@google.com#include "cpu/full_cpu/smt.hh"
3712855Sgabeblack@google.com#include "base/misc.hh"
3812855Sgabeblack@google.com
3912855Sgabeblack@google.com#include "sim/eventq.hh"
4012855Sgabeblack@google.com#include "base/trace.hh"
4112855Sgabeblack@google.com#include "sim/universe.hh"
4212855Sgabeblack@google.com
4312855Sgabeblack@google.comusing namespace std;
4412855Sgabeblack@google.com
4512855Sgabeblack@google.comconst string Event::defaultName("event");
4612855Sgabeblack@google.com
4712855Sgabeblack@google.com//
4812855Sgabeblack@google.com// Main Event Queue
4912855Sgabeblack@google.com//
5012855Sgabeblack@google.com// Events on this queue are processed at the *beginning* of each
5112855Sgabeblack@google.com// cycle, before the pipeline simulation is performed.
5212855Sgabeblack@google.com//
5312855Sgabeblack@google.comEventQueue mainEventQueue("MainEventQueue");
5412855Sgabeblack@google.com
5512855Sgabeblack@google.comvoid
5612855Sgabeblack@google.comEventQueue::insert(Event *event)
5712855Sgabeblack@google.com{
5812855Sgabeblack@google.com    if (head == NULL || event->when() < head->when() ||
5912855Sgabeblack@google.com        (event->when() == head->when() &&
6012855Sgabeblack@google.com         event->priority() <= head->priority())) {
6112855Sgabeblack@google.com        event->next = head;
6212855Sgabeblack@google.com        head = event;
6312855Sgabeblack@google.com    } else {
6412855Sgabeblack@google.com        Event *prev = head;
6512855Sgabeblack@google.com        Event *curr = head->next;
6612855Sgabeblack@google.com
6712855Sgabeblack@google.com        while (curr) {
6812855Sgabeblack@google.com            if (event->when() <= curr->when() &&
6912855Sgabeblack@google.com                (event->when() < curr->when() ||
7012855Sgabeblack@google.com                 event->priority() <= curr->priority()))
7112855Sgabeblack@google.com                break;
7212855Sgabeblack@google.com
7312855Sgabeblack@google.com            prev = curr;
7412855Sgabeblack@google.com            curr = curr->next;
7512855Sgabeblack@google.com        }
7612855Sgabeblack@google.com
7712855Sgabeblack@google.com        event->next = curr;
7812855Sgabeblack@google.com        prev->next = event;
7912855Sgabeblack@google.com    }
8012855Sgabeblack@google.com}
8112855Sgabeblack@google.com
8212855Sgabeblack@google.comvoid
8312855Sgabeblack@google.comEventQueue::remove(Event *event)
8412855Sgabeblack@google.com{
8512855Sgabeblack@google.com    if (head == NULL)
8612855Sgabeblack@google.com        return;
8712855Sgabeblack@google.com
8812855Sgabeblack@google.com    if (head == event){
8912855Sgabeblack@google.com        head = event->next;
9012855Sgabeblack@google.com        return;
9112855Sgabeblack@google.com    }
9212855Sgabeblack@google.com
9312855Sgabeblack@google.com    Event *prev = head;
9412855Sgabeblack@google.com    Event *curr = head->next;
9512855Sgabeblack@google.com    while (curr && curr != event) {
9612855Sgabeblack@google.com        prev = curr;
9712855Sgabeblack@google.com        curr = curr->next;
9812855Sgabeblack@google.com    }
9912855Sgabeblack@google.com
10012855Sgabeblack@google.com    if (curr == event)
10112855Sgabeblack@google.com        prev->next = curr->next;
10212855Sgabeblack@google.com}
103
104void
105EventQueue::serviceOne()
106{
107    Event *event = head;
108    event->clearFlags(Event::Scheduled);
109    head = event->next;
110
111    // handle action
112    if (!event->squashed())
113        event->process();
114    else
115        event->clearFlags(Event::Squashed);
116
117    if (event->getFlags(Event::AutoDelete))
118        delete event;
119}
120
121
122void
123Event::serialize(std::ostream &os)
124{
125    SERIALIZE_SCALAR(_when);
126    SERIALIZE_SCALAR(_priority);
127    SERIALIZE_ENUM(_flags);
128}
129
130
131void
132Event::unserialize(const IniFile *db, const string &section)
133{
134    if (scheduled())
135        deschedule();
136
137    UNSERIALIZE_SCALAR(_when);
138    UNSERIALIZE_SCALAR(_priority);
139
140    // need to see if original event was in a scheduled, unsquashed
141    // state, but don't want to restore those flags in the current
142    // object itself (since they aren't immediately true)
143    UNSERIALIZE_ENUM(_flags);
144    bool wasScheduled = (_flags & Scheduled) && !(_flags & Squashed);
145    _flags &= ~(Squashed | Scheduled);
146
147    if (wasScheduled) {
148        DPRINTF(Config, "rescheduling at %d\n", _when);
149        schedule(_when);
150    }
151}
152
153
154void
155EventQueue::nameChildren()
156{
157#if 0
158    int j = 0;
159
160    Event *event = head;
161    while (event) {
162        stringstream stream;
163        ccprintf(stream, "%s.event%d", name(), j++);
164        event->setName(stream.str());
165
166        event = event->next;
167    }
168#endif
169}
170
171void
172EventQueue::serialize(ostream &os)
173{
174#if 0
175    string objects = "";
176
177    Event *event = head;
178    while (event) {
179        objects += event->name();
180        objects += " ";
181        event->serialize(os);
182
183        event = event->next;
184    }
185    nameOut(os, "Serialized");
186    SERIALIZE_SCALAR(objects);
187#endif
188}
189
190void
191EventQueue::dump()
192{
193    cprintf("============================================================\n");
194    cprintf("EventQueue Dump  (cycle %d)\n", curTick);
195    cprintf("------------------------------------------------------------\n");
196
197    if (empty())
198        cprintf("<No Events>\n");
199    else {
200        Event *event = head;
201        while (event) {
202            event->dump();
203            event = event->next;
204        }
205    }
206
207    cprintf("============================================================\n");
208}
209
210
211const char *
212Event::description()
213{
214    return "generic";
215}
216
217#if TRACING_ON
218void
219Event::trace(const char *action)
220{
221    // This DPRINTF is unconditional because calls to this function
222    // are protected by an 'if (DTRACE(Event))' in the inlined Event
223    // methods.
224    //
225    // This is just a default implementation for derived classes where
226    // it's not worth doing anything special.  If you want to put a
227    // more informative message in the trace, override this method on
228    // the particular subclass where you have the information that
229    // needs to be printed.
230    DPRINTFN("%s event %s @ %d\n", description(), action, when());
231}
232#endif
233
234void
235Event::dump()
236{
237#if TRACING_ON
238    cprintf("   Created: %d\n", when_created);
239#endif
240    if (scheduled()) {
241#if TRACING_ON
242        cprintf("   Scheduled at  %d\n", when_scheduled);
243#endif
244        cprintf("   Scheduled for %d\n", when());
245    }
246    else {
247        cprintf("   Not Scheduled\n");
248    }
249}
250