The original implementation of curTick used a thread local variable,
_curEventQueue, and its getCurTick() method, to retrieve the curTick for
the currently active event queue. That meant that core.hh needed to
include eventq.hh so that the EventQueue type was available, which also
indirectly brought in a lot of other dependencies.
Unfortunately this couldn't easily be fixed by making curTick()
non-inline since this added a significant amount of overhead when
tested.
Instead, this change makes the code in core.hh/core.cc keep a pointer
directly to a Tick. The code which sets _curEventQueue now also sets
that pointer when _curEventQueue changes.
The way curTick() now reaches into the guts of the current EventQueue
directly is not great from a modularity perspective, but if curTick is
considered an extension of the EventQueue, then it's just odd that this
part is broken out into a different file.
Change-Id: I8341b40fe75e90672eb1d70e1a368975fcbfe926
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/38996
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
using namespace std;
+namespace Gem5Internal
+{
+
+__thread Tick *_curTickPtr;
+
+} // namespace Gem5Internal
+
namespace SimClock {
/// The simulated frequency of curTick(). (In ticks per second)
Tick Frequency;
#include <string>
#include "base/types.hh"
-#include "sim/eventq.hh"
+
+namespace Gem5Internal
+{
+
+// This pointer is maintained by curEventQueue in src/sim/eventq.hh.
+extern __thread Tick *_curTickPtr;
+
+} // namespace Gem5Internal
/// The universal simulation clock.
-inline Tick curTick() { return _curEventQueue->getCurTick(); }
+inline Tick curTick() { return *Gem5Internal::_curTickPtr; }
/// These are variables that are set based on the simulator frequency
///@{
#include "base/types.hh"
#include "base/uncontended_mutex.hh"
#include "debug/Event.hh"
+#include "sim/core.hh"
#include "sim/serialize.hh"
class EventQueue; // forward declaration
EventQueue *getEventQueue(uint32_t index);
inline EventQueue *curEventQueue() { return _curEventQueue; }
-inline void curEventQueue(EventQueue *q) { _curEventQueue = q; }
+inline void curEventQueue(EventQueue *q);
/**
* Common base class for Event and GlobalEvent, so they can share flag
class EventQueue
{
private:
+ friend void curEventQueue(EventQueue *);
+
std::string objName;
Event *head;
Tick _curTick;
}
};
+inline void
+curEventQueue(EventQueue *q)
+{
+ _curEventQueue = q;
+ Gem5Internal::_curTickPtr = (q == nullptr) ? nullptr : &q->_curTick;
+}
+
void dumpMainQueue();
class EventManager