eventq.cc revision 2
112838Sgabeblack@google.com/*
212838Sgabeblack@google.com * Copyright (c) 2003 The Regents of The University of Michigan
312838Sgabeblack@google.com * All rights reserved.
412838Sgabeblack@google.com *
512838Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
612838Sgabeblack@google.com * modification, are permitted provided that the following conditions are
712838Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
812838Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
912838Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
1012838Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1112838Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1212838Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1312838Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1412838Sgabeblack@google.com * this software without specific prior written permission.
1512838Sgabeblack@google.com *
1612838Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1712838Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1812838Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1912838Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2012838Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2112838Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2212838Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2312838Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2412838Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2512838Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2612838Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2712838Sgabeblack@google.com */
2812838Sgabeblack@google.com
2912838Sgabeblack@google.com#include <assert.h>
3012838Sgabeblack@google.com
3112952Sgabeblack@google.com#include <iostream>
3212953Sgabeblack@google.com#include <string>
3312960Sgabeblack@google.com#include <sstream>
3412838Sgabeblack@google.com#include <vector>
3512838Sgabeblack@google.com
3612838Sgabeblack@google.com#include "smt.hh"
3712838Sgabeblack@google.com#include "misc.hh"
3812838Sgabeblack@google.com
3912838Sgabeblack@google.com#include "eventq.hh"
4012838Sgabeblack@google.com#include "trace.hh"
4112838Sgabeblack@google.com#include "universe.hh"
4212994Sgabeblack@google.com
4312838Sgabeblack@google.comusing namespace std;
4412838Sgabeblack@google.com
4512838Sgabeblack@google.comconst string Event::defaultName("event");
4612838Sgabeblack@google.com
4712838Sgabeblack@google.com//
4812994Sgabeblack@google.com// Main Event Queue
4912838Sgabeblack@google.com//
5012838Sgabeblack@google.com// Events on this queue are processed at the *beginning* of each
5112994Sgabeblack@google.com// cycle, before the pipeline simulation is performed.
5212994Sgabeblack@google.com//
5312994Sgabeblack@google.comEventQueue mainEventQueue("Main Event Queue");
5412994Sgabeblack@google.com
5512952Sgabeblack@google.comvoid
5612838Sgabeblack@google.comEventQueue::insert(Event *event)
5712838Sgabeblack@google.com{
5812939Sgabeblack@google.com    if (head == NULL || event->when() < head->when() ||
5912939Sgabeblack@google.com        (event->when() == head->when() &&
6012939Sgabeblack@google.com         event->priority() <= head->priority())) {
6112939Sgabeblack@google.com        event->next = head;
6212939Sgabeblack@google.com        head = event;
6312939Sgabeblack@google.com    } else {
6412939Sgabeblack@google.com        Event *prev = head;
6512939Sgabeblack@google.com        Event *curr = head->next;
6612939Sgabeblack@google.com
6712939Sgabeblack@google.com        while (curr) {
6812939Sgabeblack@google.com            if (event->when() <= curr->when() &&
6912939Sgabeblack@google.com                (event->when() < curr->when() ||
7012939Sgabeblack@google.com                 event->priority() <= curr->priority()))
7112939Sgabeblack@google.com                break;
7212939Sgabeblack@google.com
7312939Sgabeblack@google.com            prev = curr;
7412939Sgabeblack@google.com            curr = curr->next;
7512939Sgabeblack@google.com        }
7612939Sgabeblack@google.com
7712939Sgabeblack@google.com        event->next = curr;
7812939Sgabeblack@google.com        prev->next = event;
7912939Sgabeblack@google.com    }
8012939Sgabeblack@google.com}
8112952Sgabeblack@google.com
8212952Sgabeblack@google.comvoid
8312952Sgabeblack@google.comEventQueue::remove(Event *event)
8412952Sgabeblack@google.com{
8512838Sgabeblack@google.com    if (head == NULL)
8612952Sgabeblack@google.com        return;
8712952Sgabeblack@google.com
8812838Sgabeblack@google.com    if (head == event){
8912838Sgabeblack@google.com        head = event->next;
9012952Sgabeblack@google.com        return;
9112952Sgabeblack@google.com    }
9212838Sgabeblack@google.com
9312952Sgabeblack@google.com    Event *prev = head;
9412952Sgabeblack@google.com    Event *curr = head->next;
9512838Sgabeblack@google.com    while (curr && curr != event) {
9612838Sgabeblack@google.com        prev = curr;
9712838Sgabeblack@google.com        curr = curr->next;
9812838Sgabeblack@google.com    }
9912952Sgabeblack@google.com
10012952Sgabeblack@google.com    if (curr == event)
10112838Sgabeblack@google.com        prev->next = curr->next;
10212838Sgabeblack@google.com}
10312838Sgabeblack@google.com
10412838Sgabeblack@google.comvoid
10512838Sgabeblack@google.comEventQueue::serviceOne()
10612838Sgabeblack@google.com{
10712952Sgabeblack@google.com    Event *event = head;
10812838Sgabeblack@google.com    event->clearFlags(Event::Scheduled);
10912838Sgabeblack@google.com    head = event->next;
11012838Sgabeblack@google.com
11112838Sgabeblack@google.com    // handle action
11212952Sgabeblack@google.com    if (!event->squashed())
11312838Sgabeblack@google.com        event->process();
11412952Sgabeblack@google.com    else
11512952Sgabeblack@google.com        event->clearFlags(Event::Squashed);
11612952Sgabeblack@google.com
11712952Sgabeblack@google.com    if (event->getFlags(Event::AutoDelete))
11812952Sgabeblack@google.com        delete event;
11912838Sgabeblack@google.com}
12012838Sgabeblack@google.com
12112838Sgabeblack@google.comvoid
12212838Sgabeblack@google.comEventQueue::nameChildren()
12312952Sgabeblack@google.com{
12412838Sgabeblack@google.com    int j = 0;
12512952Sgabeblack@google.com
12612952Sgabeblack@google.com    Event *event = head;
12712838Sgabeblack@google.com    while (event) {
12812838Sgabeblack@google.com        stringstream stream;
12912838Sgabeblack@google.com        ccprintf(stream, "%s.event%d", name(), j++);
13012952Sgabeblack@google.com        event->setName(stream.str());
13112838Sgabeblack@google.com
13212952Sgabeblack@google.com        event = event->next;
13312838Sgabeblack@google.com    }
13412838Sgabeblack@google.com}
13512838Sgabeblack@google.com
13612952Sgabeblack@google.comvoid
13712838Sgabeblack@google.comEventQueue::serialize()
13812952Sgabeblack@google.com{
13912838Sgabeblack@google.com    string objects = "";
14012838Sgabeblack@google.com
14112952Sgabeblack@google.com    Event *event = head;
14212952Sgabeblack@google.com    while (event) {
14312838Sgabeblack@google.com        objects += event->name();
14412952Sgabeblack@google.com        objects += " ";
14512952Sgabeblack@google.com        event->serialize();
14612952Sgabeblack@google.com
14712838Sgabeblack@google.com        event = event->next;
14812838Sgabeblack@google.com    }
14912838Sgabeblack@google.com    nameOut("Serialized");
15012838Sgabeblack@google.com    paramOut("objects",objects);
15112838Sgabeblack@google.com}
15212838Sgabeblack@google.com
15312952Sgabeblack@google.comvoid
15412838Sgabeblack@google.comEventQueue::dump()
15512838Sgabeblack@google.com{
15612838Sgabeblack@google.com    cprintf("============================================================\n");
15712838Sgabeblack@google.com    cprintf("EventQueue Dump  (cycle %d)\n", curTick);
15812838Sgabeblack@google.com    cprintf("------------------------------------------------------------\n");
15912952Sgabeblack@google.com
16012838Sgabeblack@google.com    if (empty())
16112838Sgabeblack@google.com        cprintf("<No Events>\n");
16212838Sgabeblack@google.com    else {
16312838Sgabeblack@google.com        Event *event = head;
16412838Sgabeblack@google.com        while (event) {
16512952Sgabeblack@google.com            event->dump();
16612952Sgabeblack@google.com            event = event->next;
16712838Sgabeblack@google.com        }
16812838Sgabeblack@google.com    }
16912838Sgabeblack@google.com
17012838Sgabeblack@google.com    cprintf("============================================================\n");
17112838Sgabeblack@google.com}
17212952Sgabeblack@google.com
17312952Sgabeblack@google.com
17412838Sgabeblack@google.comconst char *
17512838Sgabeblack@google.comEvent::description()
17612838Sgabeblack@google.com{
17712838Sgabeblack@google.com    return "generic";
17812838Sgabeblack@google.com}
17912952Sgabeblack@google.com
18012838Sgabeblack@google.com#if TRACING_ON
18112838Sgabeblack@google.comvoid
18212838Sgabeblack@google.comEvent::trace(const char *action)
18312838Sgabeblack@google.com{
18412838Sgabeblack@google.com    // This DPRINTF is unconditional because calls to this function
18512952Sgabeblack@google.com    // are protected by an 'if (DTRACE(Event))' in the inlined Event
18612838Sgabeblack@google.com    // methods.
18712838Sgabeblack@google.com    //
18812838Sgabeblack@google.com    // This is just a default implementation for derived classes where
18912838Sgabeblack@google.com    // it's not worth doing anything special.  If you want to put a
19012838Sgabeblack@google.com    // more informative message in the trace, override this method on
19112952Sgabeblack@google.com    // the particular subclass where you have the information that
19212838Sgabeblack@google.com    // needs to be printed.
19312838Sgabeblack@google.com    DPRINTFN("%s event %s @ %d\n", description(), action, when());
19412838Sgabeblack@google.com}
19512838Sgabeblack@google.com#endif
19612838Sgabeblack@google.com
19712952Sgabeblack@google.comvoid
19812838Sgabeblack@google.comEvent::dump()
19912838Sgabeblack@google.com{
20012838Sgabeblack@google.com#if TRACING_ON
20112838Sgabeblack@google.com    cprintf("   Created: %d\n", when_created);
20212838Sgabeblack@google.com#endif
20312952Sgabeblack@google.com    if (scheduled()) {
20412952Sgabeblack@google.com#if TRACING_ON
20512838Sgabeblack@google.com        cprintf("   Scheduled at  %d\n", when_scheduled);
20612838Sgabeblack@google.com#endif
20712838Sgabeblack@google.com        cprintf("   Scheduled for %d\n", when());
20812838Sgabeblack@google.com    }
20912838Sgabeblack@google.com    else {
21012838Sgabeblack@google.com        cprintf("   Not Scheduled\n");
21112952Sgabeblack@google.com    }
21212952Sgabeblack@google.com}
21312952Sgabeblack@google.com