eventq.hh (9979:329b8a20958b) | eventq.hh (9983:2cce74fe359e) |
---|---|
1/* 2 * Copyright (c) 2000-2005 The Regents of The University of Michigan | 1/* 2 * Copyright (c) 2000-2005 The Regents of The University of Michigan |
3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * Copyright (c) 2013 Mark D. Hill and David A. Wood |
|
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the --- 24 unchanged lines hidden (view full) --- 35 36#ifndef __SIM_EVENTQ_HH__ 37#define __SIM_EVENTQ_HH__ 38 39#include <algorithm> 40#include <cassert> 41#include <climits> 42#include <iosfwd> | 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer; 11 * redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the --- 24 unchanged lines hidden (view full) --- 37 38#ifndef __SIM_EVENTQ_HH__ 39#define __SIM_EVENTQ_HH__ 40 41#include <algorithm> 42#include <cassert> 43#include <climits> 44#include <iosfwd> |
45#include <mutex> |
|
43#include <string> 44 45#include "base/flags.hh" 46#include "base/misc.hh" 47#include "base/types.hh" 48#include "debug/Event.hh" 49#include "sim/serialize.hh" 50 51class EventQueue; // forward declaration | 46#include <string> 47 48#include "base/flags.hh" 49#include "base/misc.hh" 50#include "base/types.hh" 51#include "debug/Event.hh" 52#include "sim/serialize.hh" 53 54class EventQueue; // forward declaration |
55class BaseGlobalEvent; |
|
52 | 56 |
53extern EventQueue mainEventQueue; | 57//! Simulation Quantum for multiple eventq simulation. 58//! The quantum value is the period length after which the queues 59//! synchronize themselves with each other. This means that any 60//! event to scheduled on Queue A which is generated by an event on 61//! Queue B should be at least simQuantum ticks away in future. 62extern Tick simQuantum; |
54 | 63 |
55/* 56 * An item on an event queue. The action caused by a given 57 * event is specified by deriving a subclass and overriding the 58 * process() member function. 59 * 60 * Caution, the order of members is chosen to maximize data packing. | 64//! Current number of allocated main event queues. 65extern uint32_t numMainEventQueues; 66 67//! Array for main event queues. 68extern std::vector<EventQueue *> mainEventQueue; 69 70#ifndef SWIG 71//! The current event queue for the running thread. Access to this queue 72//! does not require any locking from the thread. 73 74extern __thread EventQueue *_curEventQueue; 75 76#endif 77 78//! Current mode of execution: parallel / serial 79extern bool inParallelMode; 80 81//! Function for returning eventq queue for the provided 82//! index. The function allocates a new queue in case one 83//! does not exist for the index, provided that the index 84//! is with in bounds. 85EventQueue *getEventQueue(uint32_t index); 86 87inline EventQueue *curEventQueue() { return _curEventQueue; } 88inline void curEventQueue(EventQueue *q) { _curEventQueue = q; } 89 90/** 91 * Common base class for Event and GlobalEvent, so they can share flag 92 * and priority definitions and accessor functions. This class should 93 * not be used directly. |
61 */ | 94 */ |
62class Event : public Serializable | 95class EventBase |
63{ | 96{ |
64 friend class EventQueue; 65 | |
66 protected: 67 typedef unsigned short FlagsType; 68 typedef ::Flags<FlagsType> Flags; 69 70 static const FlagsType PublicRead = 0x003f; // public readable flags 71 static const FlagsType PublicWrite = 0x001d; // public writable flags 72 static const FlagsType Squashed = 0x0001; // has been squashed 73 static const FlagsType Scheduled = 0x0002; // has been scheduled 74 static const FlagsType AutoDelete = 0x0004; // delete after dispatch 75 static const FlagsType AutoSerialize = 0x0008; // must be serialized 76 static const FlagsType IsExitEvent = 0x0010; // special exit event 77 static const FlagsType IsMainQueue = 0x0020; // on main event queue 78 static const FlagsType Initialized = 0x7a40; // somewhat random bits 79 static const FlagsType InitMask = 0xffc0; // mask for init bits 80 | 97 protected: 98 typedef unsigned short FlagsType; 99 typedef ::Flags<FlagsType> Flags; 100 101 static const FlagsType PublicRead = 0x003f; // public readable flags 102 static const FlagsType PublicWrite = 0x001d; // public writable flags 103 static const FlagsType Squashed = 0x0001; // has been squashed 104 static const FlagsType Scheduled = 0x0002; // has been scheduled 105 static const FlagsType AutoDelete = 0x0004; // delete after dispatch 106 static const FlagsType AutoSerialize = 0x0008; // must be serialized 107 static const FlagsType IsExitEvent = 0x0010; // special exit event 108 static const FlagsType IsMainQueue = 0x0020; // on main event queue 109 static const FlagsType Initialized = 0x7a40; // somewhat random bits 110 static const FlagsType InitMask = 0xffc0; // mask for init bits 111 |
81 bool 82 initialized() const 83 { 84 return this && (flags & InitMask) == Initialized; 85 } 86 | |
87 public: 88 typedef int8_t Priority; 89 | 112 public: 113 typedef int8_t Priority; 114 |
115 /// Event priorities, to provide tie-breakers for events scheduled 116 /// at the same cycle. Most events are scheduled at the default 117 /// priority; these values are used to control events that need to 118 /// be ordered within a cycle. 119 120 /// Minimum priority 121 static const Priority Minimum_Pri = SCHAR_MIN; 122 123 /// If we enable tracing on a particular cycle, do that as the 124 /// very first thing so we don't miss any of the events on 125 /// that cycle (even if we enter the debugger). 126 static const Priority Debug_Enable_Pri = -101; 127 128 /// Breakpoints should happen before anything else (except 129 /// enabling trace output), so we don't miss any action when 130 /// debugging. 131 static const Priority Debug_Break_Pri = -100; 132 133 /// CPU switches schedule the new CPU's tick event for the 134 /// same cycle (after unscheduling the old CPU's tick event). 135 /// The switch needs to come before any tick events to make 136 /// sure we don't tick both CPUs in the same cycle. 137 static const Priority CPU_Switch_Pri = -31; 138 139 /// For some reason "delayed" inter-cluster writebacks are 140 /// scheduled before regular writebacks (which have default 141 /// priority). Steve? 142 static const Priority Delayed_Writeback_Pri = -1; 143 144 /// Default is zero for historical reasons. 145 static const Priority Default_Pri = 0; 146 147 /// Serailization needs to occur before tick events also, so 148 /// that a serialize/unserialize is identical to an on-line 149 /// CPU switch. 150 static const Priority Serialize_Pri = 32; 151 152 /// CPU ticks must come after other associated CPU events 153 /// (such as writebacks). 154 static const Priority CPU_Tick_Pri = 50; 155 156 /// Statistics events (dump, reset, etc.) come after 157 /// everything else, but before exit. 158 static const Priority Stat_Event_Pri = 90; 159 160 /// Progress events come at the end. 161 static const Priority Progress_Event_Pri = 95; 162 163 /// If we want to exit on this cycle, it's the very last thing 164 /// we do. 165 static const Priority Sim_Exit_Pri = 100; 166 167 /// Maximum priority 168 static const Priority Maximum_Pri = SCHAR_MAX; 169}; 170 171/* 172 * An item on an event queue. The action caused by a given 173 * event is specified by deriving a subclass and overriding the 174 * process() member function. 175 * 176 * Caution, the order of members is chosen to maximize data packing. 177 */ 178class Event : public EventBase, public Serializable 179{ 180 friend class EventQueue; 181 |
|
90 private: 91 // The event queue is now a linked list of linked lists. The 92 // 'nextBin' pointer is to find the bin, where a bin is defined as 93 // when+priority. All events in the same bin will be stored in a 94 // second linked list (a stack) maintained by the 'nextInBin' 95 // pointer. The list will be accessed in LIFO order. The end 96 // result is that the insert/removal in 'nextBin' is 97 // linear/constant, and the lookup/removal in 'nextInBin' is --- 36 unchanged lines hidden (view full) --- 134#ifndef NDEBUG 135 queue = q; 136#endif 137#ifdef EVENTQ_DEBUG 138 whenScheduled = curTick(); 139#endif 140 } 141 | 182 private: 183 // The event queue is now a linked list of linked lists. The 184 // 'nextBin' pointer is to find the bin, where a bin is defined as 185 // when+priority. All events in the same bin will be stored in a 186 // second linked list (a stack) maintained by the 'nextInBin' 187 // pointer. The list will be accessed in LIFO order. The end 188 // result is that the insert/removal in 'nextBin' is 189 // linear/constant, and the lookup/removal in 'nextInBin' is --- 36 unchanged lines hidden (view full) --- 226#ifndef NDEBUG 227 queue = q; 228#endif 229#ifdef EVENTQ_DEBUG 230 whenScheduled = curTick(); 231#endif 232 } 233 |
234 bool 235 initialized() const 236 { 237 return this && (flags & InitMask) == Initialized; 238 } 239 |
|
142 protected: 143 /// Accessor for flags. 144 Flags 145 getFlags() const 146 { 147 return flags & PublicRead; 148 } 149 --- 24 unchanged lines hidden (view full) --- 174 { 175 flags.clear(PublicWrite); 176 } 177 178 // This function isn't really useful if TRACING_ON is not defined 179 virtual void trace(const char *action); //!< trace event activity 180 181 public: | 240 protected: 241 /// Accessor for flags. 242 Flags 243 getFlags() const 244 { 245 return flags & PublicRead; 246 } 247 --- 24 unchanged lines hidden (view full) --- 272 { 273 flags.clear(PublicWrite); 274 } 275 276 // This function isn't really useful if TRACING_ON is not defined 277 virtual void trace(const char *action); //!< trace event activity 278 279 public: |
182 /// Event priorities, to provide tie-breakers for events scheduled 183 /// at the same cycle. Most events are scheduled at the default 184 /// priority; these values are used to control events that need to 185 /// be ordered within a cycle. | |
186 | 280 |
187 /// Minimum priority 188 static const Priority Minimum_Pri = SCHAR_MIN; 189 190 /// If we enable tracing on a particular cycle, do that as the 191 /// very first thing so we don't miss any of the events on 192 /// that cycle (even if we enter the debugger). 193 static const Priority Debug_Enable_Pri = -101; 194 195 /// Breakpoints should happen before anything else (except 196 /// enabling trace output), so we don't miss any action when 197 /// debugging. 198 static const Priority Debug_Break_Pri = -100; 199 200 /// CPU switches schedule the new CPU's tick event for the 201 /// same cycle (after unscheduling the old CPU's tick event). 202 /// The switch needs to come before any tick events to make 203 /// sure we don't tick both CPUs in the same cycle. 204 static const Priority CPU_Switch_Pri = -31; 205 206 /// For some reason "delayed" inter-cluster writebacks are 207 /// scheduled before regular writebacks (which have default 208 /// priority). Steve? 209 static const Priority Delayed_Writeback_Pri = -1; 210 211 /// Default is zero for historical reasons. 212 static const Priority Default_Pri = 0; 213 214 /// Serailization needs to occur before tick events also, so 215 /// that a serialize/unserialize is identical to an on-line 216 /// CPU switch. 217 static const Priority Serialize_Pri = 32; 218 219 /// CPU ticks must come after other associated CPU events 220 /// (such as writebacks). 221 static const Priority CPU_Tick_Pri = 50; 222 223 /// Statistics events (dump, reset, etc.) come after 224 /// everything else, but before exit. 225 static const Priority Stat_Event_Pri = 90; 226 227 /// Progress events come at the end. 228 static const Priority Progress_Event_Pri = 95; 229 230 /// If we want to exit on this cycle, it's the very last thing 231 /// we do. 232 static const Priority Sim_Exit_Pri = 100; 233 234 /// Maximum priority 235 static const Priority Maximum_Pri = SCHAR_MAX; 236 | |
237 /* 238 * Event constructor 239 * @param queue that the event gets scheduled on 240 */ 241 Event(Priority p = Default_Pri, Flags f = 0) 242 : nextBin(NULL), nextInBin(NULL), _priority(p), 243 flags(Initialized | f) 244 { --- 45 unchanged lines hidden (view full) --- 290 bool isExitEvent() const { return flags.isSet(IsExitEvent); } 291 292 /// Get the time that the event is scheduled 293 Tick when() const { return _when; } 294 295 /// Get the event priority 296 Priority priority() const { return _priority; } 297 | 281 /* 282 * Event constructor 283 * @param queue that the event gets scheduled on 284 */ 285 Event(Priority p = Default_Pri, Flags f = 0) 286 : nextBin(NULL), nextInBin(NULL), _priority(p), 287 flags(Initialized | f) 288 { --- 45 unchanged lines hidden (view full) --- 334 bool isExitEvent() const { return flags.isSet(IsExitEvent); } 335 336 /// Get the time that the event is scheduled 337 Tick when() const { return _when; } 338 339 /// Get the event priority 340 Priority priority() const { return _priority; } 341 |
342 //! If this is part of a GlobalEvent, return the pointer to the 343 //! Global Event. By default, there is no GlobalEvent, so return 344 //! NULL. (Overridden in GlobalEvent::BarrierEvent.) 345 virtual BaseGlobalEvent *globalEvent() { return NULL; } 346 |
|
298#ifndef SWIG 299 virtual void serialize(std::ostream &os); 300 virtual void unserialize(Checkpoint *cp, const std::string §ion); | 347#ifndef SWIG 348 virtual void serialize(std::ostream &os); 349 virtual void unserialize(Checkpoint *cp, const std::string §ion); |
350 351 //! This function is required to support restoring from checkpoints 352 //! when running with multiple queues. Since we still have not thrashed 353 //! out all the details on checkpointing, this function is most likely 354 //! to be revisited in future. 355 virtual void unserialize(Checkpoint *cp, const std::string §ion, 356 EventQueue *eventq); |
|
301#endif 302}; 303 304#ifndef SWIG 305inline bool 306operator<(const Event &l, const Event &r) 307{ 308 return l.when() < r.when() || --- 38 unchanged lines hidden (view full) --- 347 */ 348class EventQueue : public Serializable 349{ 350 private: 351 std::string objName; 352 Event *head; 353 Tick _curTick; 354 | 357#endif 358}; 359 360#ifndef SWIG 361inline bool 362operator<(const Event &l, const Event &r) 363{ 364 return l.when() < r.when() || --- 38 unchanged lines hidden (view full) --- 403 */ 404class EventQueue : public Serializable 405{ 406 private: 407 std::string objName; 408 Event *head; 409 Tick _curTick; 410 |
411 //! Mutex to protect async queue. 412 std::mutex *async_queue_mutex; 413 414 //! List of events added by other threads to this event queue. 415 std::list<Event*> async_queue; 416 417 //! Insert / remove event from the queue. Should only be called 418 //! by thread operating this queue. |
|
355 void insert(Event *event); 356 void remove(Event *event); 357 | 419 void insert(Event *event); 420 void remove(Event *event); 421 |
422 //! Function for adding events to the async queue. The added events 423 //! are added to main event queue later. Threads, other than the 424 //! owning thread, should call this function instead of insert(). 425 void asyncInsert(Event *event); 426 |
|
358 EventQueue(const EventQueue &); | 427 EventQueue(const EventQueue &); |
359 const EventQueue &operator=(const EventQueue &); | |
360 361 public: 362 EventQueue(const std::string &n); 363 364 virtual const std::string name() const { return objName; } | 428 429 public: 430 EventQueue(const std::string &n); 431 432 virtual const std::string name() const { return objName; } |
433 void name(const std::string &st) { objName = st; } |
|
365 | 434 |
366 // schedule the given event on this queue 367 void schedule(Event *event, Tick when); | 435 //! Schedule the given event on this queue. Safe to call from any 436 //! thread. 437 void schedule(Event *event, Tick when, bool global = false); 438 439 //! Deschedule the specified event. Should be called only from the 440 //! owning thread. |
368 void deschedule(Event *event); | 441 void deschedule(Event *event); |
442 443 //! Reschedule the specified event. Should be called only from 444 //! the owning thread. |
|
369 void reschedule(Event *event, Tick when, bool always = false); 370 371 Tick nextTick() const { return head->when(); } 372 void setCurTick(Tick newVal) { _curTick = newVal; } 373 Tick getCurTick() { return _curTick; } 374 375 Event *serviceOne(); 376 --- 20 unchanged lines hidden (view full) --- 397 398 // return true if no events are queued 399 bool empty() const { return head == NULL; } 400 401 void dump() const; 402 403 bool debugVerify() const; 404 | 445 void reschedule(Event *event, Tick when, bool always = false); 446 447 Tick nextTick() const { return head->when(); } 448 void setCurTick(Tick newVal) { _curTick = newVal; } 449 Tick getCurTick() { return _curTick; } 450 451 Event *serviceOne(); 452 --- 20 unchanged lines hidden (view full) --- 473 474 // return true if no events are queued 475 bool empty() const { return head == NULL; } 476 477 void dump() const; 478 479 bool debugVerify() const; 480 |
481 //! Function for moving events from the async_queue to the main queue. 482 void handleAsyncInsertions(); 483 |
|
405 /** 406 * function for replacing the head of the event queue, so that a 407 * different set of events can run without disturbing events that have 408 * already been scheduled. Already scheduled events can be processed 409 * by replacing the original head back. 410 * USING THIS FUNCTION CAN BE DANGEROUS TO THE HEALTH OF THE SIMULATOR. 411 * NOT RECOMMENDED FOR USE. 412 */ --- 121 unchanged lines hidden --- | 484 /** 485 * function for replacing the head of the event queue, so that a 486 * different set of events can run without disturbing events that have 487 * already been scheduled. Already scheduled events can be processed 488 * by replacing the original head back. 489 * USING THIS FUNCTION CAN BE DANGEROUS TO THE HEALTH OF THE SIMULATOR. 490 * NOT RECOMMENDED FOR USE. 491 */ --- 121 unchanged lines hidden --- |