sim: handle async events in main thread only

In the current implementation pollqueue is not thread safe. The design
of multi threads handle async events is thus causing issue in parallel
environment. Given the low rate of async events, it should be OK to only
handle them in the main thread to avoid unexpected racing issues.

Change-Id: Iddd512235e84e9d77f60985bb1771aa4cc693004
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67533
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Earl Ou
2023-02-01 21:55:51 -08:00
parent 7371e46822
commit e44cbe724b

View File

@@ -43,7 +43,6 @@
#include "sim/simulate.hh"
#include <atomic>
#include <mutex>
#include <thread>
#include "base/logging.hh"
@@ -273,28 +272,6 @@ terminateEventQueueThreads()
}
/**
* Test and clear the global async_event flag, such that each time the
* flag is cleared, only one thread returns true (and thus is assigned
* to handle the corresponding async event(s)).
*/
static bool
testAndClearAsyncEvent()
{
static std::mutex mutex;
bool was_set = false;
mutex.lock();
if (async_event) {
was_set = true;
async_event = false;
}
mutex.unlock();
return was_set;
}
/**
* The main per-thread simulation loop. This loop is executed by all
* simulation threads (the main thread and the subordinate threads) in
@@ -307,6 +284,8 @@ doSimLoop(EventQueue *eventq)
curEventQueue(eventq);
eventq->handleAsyncInsertions();
bool mainQueue = eventq == getEventQueue(0);
while (1) {
// there should always be at least one event (the SimLoopExitEvent
// we just scheduled) in the queue
@@ -314,7 +293,8 @@ doSimLoop(EventQueue *eventq)
assert(curTick() <= eventq->nextTick() &&
"event scheduled in the past");
if (async_event && testAndClearAsyncEvent()) {
if (mainQueue && async_event) {
async_event = false;
// Take the event queue lock in case any of the service
// routines want to schedule new events.
std::lock_guard<EventQueue> lock(*eventq);