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 &section);
347#ifndef SWIG
348 virtual void serialize(std::ostream &os);
349 virtual void unserialize(Checkpoint *cp, const std::string &section);
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 &section,
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 ---