eventq.cc revision 4167
17735SN/A/*
27735SN/A * Copyright (c) 2000-2005 The Regents of The University of Michigan
37735SN/A * All rights reserved.
49988Snilay@cs.wisc.edu *
58835SAli.Saidi@ARM.com * Redistribution and use in source and binary forms, with or without
69988Snilay@cs.wisc.edu * modification, are permitted provided that the following conditions are
77935SN/A * met: redistributions of source code must retain the above copyright
87935SN/A * notice, this list of conditions and the following disclaimer;
97935SN/A * redistributions in binary form must reproduce the above copyright
107735SN/A * notice, this list of conditions and the following disclaimer in the
117735SN/A * documentation and/or other materials provided with the distribution;
127735SN/A * neither the name of the copyright holders nor the names of its
1310315Snilay@cs.wisc.edu * contributors may be used to endorse or promote products derived from
1410513SAli.Saidi@ARM.com * this software without specific prior written permission.
1511268Satgutier@umich.edu *
1610513SAli.Saidi@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
179885Sstever@gmail.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
189885Sstever@gmail.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911268Satgutier@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
209055Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
219481Snilay@cs.wisc.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
229988Snilay@cs.wisc.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2310513SAli.Saidi@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2410513SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2510038SAli.Saidi@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2610038SAli.Saidi@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2710038SAli.Saidi@ARM.com *
2810038SAli.Saidi@ARM.com * Authors: Steve Reinhardt
2910038SAli.Saidi@ARM.com *          Nathan Binkert
307735SN/A *          Steve Raasch
3111268Satgutier@umich.edu */
3210315Snilay@cs.wisc.edu
337735SN/A#include <assert.h>
3410513SAli.Saidi@ARM.com
3510513SAli.Saidi@ARM.com#include <iostream>
367735SN/A#include <string>
3710513SAli.Saidi@ARM.com#include <vector>
3810636Snilay@cs.wisc.edu
3910736Snilay@cs.wisc.edu#include "cpu/smt.hh"
409079SAli.Saidi@ARM.com#include "base/misc.hh"
4111219Snilay@cs.wisc.edu
428721SN/A#include "sim/eventq.hh"
439885Sstever@gmail.com#include "base/trace.hh"
449885Sstever@gmail.com#include "sim/core.hh"
4510038SAli.Saidi@ARM.com
4611268Satgutier@umich.eduusing namespace std;
4710038SAli.Saidi@ARM.com
487735SN/A//
497935SN/A// Main Event Queue
507935SN/A//
517935SN/A// Events on this queue are processed at the *beginning* of each
527935SN/A// cycle, before the pipeline simulation is performed.
537935SN/A//
547935SN/AEventQueue mainEventQueue("MainEventQueue");
557935SN/A
5610513SAli.Saidi@ARM.com#ifndef NDEBUG
577735SN/ACounter Event::instanceCounter = 0;
587735SN/A#endif
597735SN/A
609885Sstever@gmail.comvoid
617735SN/AEventQueue::insert(Event *event)
629988Snilay@cs.wisc.edu{
6310513SAli.Saidi@ARM.com    if (head == NULL || event->when() < head->when() ||
648721SN/A        (event->when() == head->when() &&
658721SN/A         event->priority() <= head->priority())) {
668891SAli.Saidi@ARM.com        event->next = head;
678891SAli.Saidi@ARM.com        head = event;
687735SN/A    } else {
698528SN/A        Event *prev = head;
708528SN/A        Event *curr = head->next;
718528SN/A
728528SN/A        while (curr) {
738528SN/A            if (event->when() <= curr->when() &&
749988Snilay@cs.wisc.edu                (event->when() < curr->when() ||
758528SN/A                 event->priority() <= curr->priority()))
768528SN/A                break;
778528SN/A
788528SN/A            prev = curr;
798528SN/A            curr = curr->next;
808528SN/A        }
819988Snilay@cs.wisc.edu
828528SN/A        event->next = curr;
838528SN/A        prev->next = event;
848528SN/A    }
858528SN/A}
868528SN/A
878528SN/Avoid
889988Snilay@cs.wisc.eduEventQueue::remove(Event *event)
8911268Satgutier@umich.edu{
908528SN/A    if (head == NULL)
918528SN/A        return;
929885Sstever@gmail.com
939885Sstever@gmail.com    if (head == event){
949885Sstever@gmail.com        head = event->next;
9510315Snilay@cs.wisc.edu        return;
969988Snilay@cs.wisc.edu    }
9710315Snilay@cs.wisc.edu
989885Sstever@gmail.com    Event *prev = head;
999885Sstever@gmail.com    Event *curr = head->next;
1007735SN/A    while (curr && curr != event) {
1017735SN/A        prev = curr;
10210038SAli.Saidi@ARM.com        curr = curr->next;
10310315Snilay@cs.wisc.edu    }
1047735SN/A
1059885Sstever@gmail.com    if (curr == event)
1067735SN/A        prev->next = curr->next;
1077735SN/A}
1087735SN/A
1097735SN/AEvent *
11010038SAli.Saidi@ARM.comEventQueue::serviceOne()
1117735SN/A{
1129988Snilay@cs.wisc.edu    Event *event = head;
1138983Snate@binkert.org    event->clearFlags(Event::Scheduled);
1147735SN/A    head = event->next;
1157735SN/A
1167735SN/A    // handle action
1179481Snilay@cs.wisc.edu    if (!event->squashed()) {
11810038SAli.Saidi@ARM.com        event->process();
1197735SN/A        if (event->isExitEvent()) {
1207735SN/A            assert(!event->getFlags(Event::AutoDelete)); // would be silly
1217735SN/A            return event;
1227735SN/A        }
1237735SN/A    } else {
1247735SN/A        event->clearFlags(Event::Squashed);
1257735SN/A    }
1267735SN/A
1279885Sstever@gmail.com    if (event->getFlags(Event::AutoDelete) && !event->scheduled())
1287735SN/A        delete event;
1297735SN/A
13010315Snilay@cs.wisc.edu    return NULL;
1319481Snilay@cs.wisc.edu}
1327735SN/A
1337735SN/A
1347735SN/Avoid
1358835SAli.Saidi@ARM.comEvent::serialize(std::ostream &os)
1367735SN/A{
1377735SN/A    SERIALIZE_SCALAR(_when);
1387735SN/A    SERIALIZE_SCALAR(_priority);
1397735SN/A    SERIALIZE_ENUM(_flags);
14011103Snilay@cs.wisc.edu}
1419885Sstever@gmail.com
1428891SAli.Saidi@ARM.com
1437735SN/Avoid
1449885Sstever@gmail.comEvent::unserialize(Checkpoint *cp, const string &section)
14511219Snilay@cs.wisc.edu{
14610636Snilay@cs.wisc.edu    if (scheduled())
1479988Snilay@cs.wisc.edu        deschedule();
1487735SN/A
1499481Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(_when);
15011014Sandreas.sandberg@arm.com    UNSERIALIZE_SCALAR(_priority);
1517735SN/A
1527735SN/A    // need to see if original event was in a scheduled, unsquashed
1537735SN/A    // state, but don't want to restore those flags in the current
1548835SAli.Saidi@ARM.com    // object itself (since they aren't immediately true)
1559481Snilay@cs.wisc.edu    UNSERIALIZE_ENUM(_flags);
15610036SAli.Saidi@ARM.com    bool wasScheduled = (_flags & Scheduled) && !(_flags & Squashed);
1577735SN/A    _flags &= ~(Squashed | Scheduled);
1588835SAli.Saidi@ARM.com
1599885Sstever@gmail.com    if (wasScheduled) {
1609481Snilay@cs.wisc.edu        DPRINTF(Config, "rescheduling at %d\n", _when);
1617735SN/A        schedule(_when);
16211219Snilay@cs.wisc.edu    }
1637735SN/A}
1649481Snilay@cs.wisc.edu
1657735SN/Avoid
1669885Sstever@gmail.comEventQueue::serialize(ostream &os)
1679885Sstever@gmail.com{
1689885Sstever@gmail.com    std::list<Event *> eventPtrs;
1699885Sstever@gmail.com
1709885Sstever@gmail.com    int numEvents = 0;
1719988Snilay@cs.wisc.edu    Event *event = head;
1729885Sstever@gmail.com    while (event) {
17310036SAli.Saidi@ARM.com        if (event->getFlags(Event::AutoSerialize)) {
1749885Sstever@gmail.com            eventPtrs.push_back(event);
1759885Sstever@gmail.com            paramOut(os, csprintf("event%d", numEvents++), event->name());
17610038SAli.Saidi@ARM.com        }
17710038SAli.Saidi@ARM.com        event = event->next;
17810038SAli.Saidi@ARM.com    }
17910038SAli.Saidi@ARM.com
18010038SAli.Saidi@ARM.com    SERIALIZE_SCALAR(numEvents);
18110736Snilay@cs.wisc.edu
18210038SAli.Saidi@ARM.com    for (std::list<Event *>::iterator it=eventPtrs.begin();
18310038SAli.Saidi@ARM.com         it != eventPtrs.end(); ++it) {
18410038SAli.Saidi@ARM.com        (*it)->nameOut(os);
18510038SAli.Saidi@ARM.com        (*it)->serialize(os);
18610038SAli.Saidi@ARM.com    }
18710038SAli.Saidi@ARM.com}
18810038SAli.Saidi@ARM.com
18910038SAli.Saidi@ARM.comvoid
19010038SAli.Saidi@ARM.comEventQueue::unserialize(Checkpoint *cp, const std::string &section)
19110038SAli.Saidi@ARM.com{
19210038SAli.Saidi@ARM.com    int numEvents;
19310038SAli.Saidi@ARM.com    UNSERIALIZE_SCALAR(numEvents);
19410038SAli.Saidi@ARM.com
19510038SAli.Saidi@ARM.com    std::string eventName;
19610038SAli.Saidi@ARM.com    for (int i = 0; i < numEvents; i++) {
19710038SAli.Saidi@ARM.com        // get the pointer value associated with the event
19810038SAli.Saidi@ARM.com        paramIn(cp, section, csprintf("event%d", i), eventName);
19910038SAli.Saidi@ARM.com
2007735SN/A        // create the event based on its pointer value
2017735SN/A        Serializable::create(cp, eventName);
2027735SN/A    }
2039988Snilay@cs.wisc.edu}
20410038SAli.Saidi@ARM.com
2057735SN/Avoid
2067735SN/AEventQueue::dump()
2077735SN/A{
2087735SN/A    cprintf("============================================================\n");
2097735SN/A    cprintf("EventQueue Dump  (cycle %d)\n", curTick);
2109885Sstever@gmail.com    cprintf("------------------------------------------------------------\n");
2119988Snilay@cs.wisc.edu
21210038SAli.Saidi@ARM.com    if (empty())
2139265SAli.Saidi@ARM.com        cprintf("<No Events>\n");
2147735SN/A    else {
2159481Snilay@cs.wisc.edu        Event *event = head;
2167735SN/A        while (event) {
2177735SN/A            event->dump();
21811103Snilay@cs.wisc.edu            event = event->next;
2199885Sstever@gmail.com        }
2208891SAli.Saidi@ARM.com    }
2217735SN/A
2229885Sstever@gmail.com    cprintf("============================================================\n");
22311219Snilay@cs.wisc.edu}
22410636Snilay@cs.wisc.edu
2259988Snilay@cs.wisc.eduextern "C"
2267735SN/Avoid
2279481Snilay@cs.wisc.edudumpMainQueue()
22811014Sandreas.sandberg@arm.com{
2297735SN/A    mainEventQueue.dump();
2307735SN/A}
2317735SN/A
2328835SAli.Saidi@ARM.com
2339481Snilay@cs.wisc.educonst char *
23410036SAli.Saidi@ARM.comEvent::description()
2357735SN/A{
2368835SAli.Saidi@ARM.com    return "generic";
2379885Sstever@gmail.com}
2389481Snilay@cs.wisc.edu
2397735SN/A#if TRACING_ON
24011219Snilay@cs.wisc.eduvoid
2417735SN/AEvent::trace(const char *action)
2429481Snilay@cs.wisc.edu{
2437735SN/A    // This DPRINTF is unconditional because calls to this function
2449885Sstever@gmail.com    // are protected by an 'if (DTRACE(Event))' in the inlined Event
2459885Sstever@gmail.com    // methods.
2469885Sstever@gmail.com    //
2479885Sstever@gmail.com    // This is just a default implementation for derived classes where
2489885Sstever@gmail.com    // it's not worth doing anything special.  If you want to put a
2499988Snilay@cs.wisc.edu    // more informative message in the trace, override this method on
2509885Sstever@gmail.com    // the particular subclass where you have the information that
25110036SAli.Saidi@ARM.com    // needs to be printed.
2529885Sstever@gmail.com    DPRINTFN("%s event %s @ %d\n", description(), action, when());
2539885Sstever@gmail.com}
2547735SN/A#endif
2557735SN/A
2569988Snilay@cs.wisc.eduvoid
2577735SN/AEvent::dump()
2589481Snilay@cs.wisc.edu{
2599481Snilay@cs.wisc.edu    cprintf("Event  (%s)\n", description());
26011219Snilay@cs.wisc.edu    cprintf("Flags: %#x\n", _flags);
2619988Snilay@cs.wisc.edu#if TRACING_ON
2629481Snilay@cs.wisc.edu    cprintf("Created: %d\n", when_created);
26310038SAli.Saidi@ARM.com#endif
26410038SAli.Saidi@ARM.com    if (scheduled()) {
26510038SAli.Saidi@ARM.com#if TRACING_ON
26610038SAli.Saidi@ARM.com        cprintf("Scheduled at  %d\n", when_scheduled);
26710038SAli.Saidi@ARM.com#endif
26810038SAli.Saidi@ARM.com        cprintf("Scheduled for %d, priority %d\n", when(), _priority);
26910038SAli.Saidi@ARM.com    }
27010038SAli.Saidi@ARM.com    else {
27110038SAli.Saidi@ARM.com        cprintf("Not Scheduled\n");
27210038SAli.Saidi@ARM.com    }
2739481Snilay@cs.wisc.edu}
2749481Snilay@cs.wisc.edu