Skip to content

Commit 8c4a2e2

Browse files
Make sc_event thread safe
Signed-off-by: Mark Burton <mburton@quicinc.com>
1 parent b4dada7 commit 8c4a2e2

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

src/sysc/kernel/sc_event.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <cstring>
3131

3232
#include "sysc/kernel/sc_event.h"
33+
#include "sc_simcontext.h"
3334
#include "sysc/kernel/sc_kernel_ids.h"
3435
#include "sysc/kernel/sc_stage_callback_registry.h"
3536
#include "sysc/kernel/sc_process.h"
@@ -61,6 +62,10 @@ sc_event::basename() const
6162
void
6263
sc_event::cancel()
6364
{
65+
if (m_simc != sc_get_curr_simcontext()) {
66+
async_helper.pending_cancel();
67+
return;
68+
}
6469
// cancel a delta or timed notification
6570
switch( m_notify_type ) {
6671
case DELTA: {
@@ -86,6 +91,10 @@ sc_event::cancel()
8691
void
8792
sc_event::notify()
8893
{
94+
if (m_simc != sc_get_curr_simcontext()) {
95+
async_helper.pending_notify(SC_ZERO_TIME);
96+
return;
97+
}
8998
// immediate notification
9099
if( !m_simc->evaluation_phase() )
91100
// coming from
@@ -103,6 +112,10 @@ sc_event::notify()
103112
void
104113
sc_event::notify( const sc_time& t )
105114
{
115+
if (m_simc != sc_get_curr_simcontext()) {
116+
async_helper.pending_notify(t);
117+
return;
118+
}
106119
if( m_notify_type == DELTA ) {
107120
return;
108121
}

src/sysc/kernel/sc_event.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "sysc/kernel/sc_simcontext.h"
3636
#include "sysc/communication/sc_writer_policy.h"
3737
#include "sysc/utils/sc_ptr_flag.h"
38+
#include <mutex>
3839

3940
#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
4041
#pragma warning(push)
@@ -273,6 +274,43 @@ class SC_API sc_event
273274
friend class sc_join;
274275
friend class sc_trace_file;
275276

277+
class pending_helper : public sc_core::sc_stage_callback_if
278+
{
279+
std::mutex mutex;
280+
class sc_event *event;
281+
282+
bool valid=false;
283+
bool cancel=false;
284+
sc_time time;
285+
286+
void stage_callback(const sc_core::sc_stage& stage) {
287+
mutex.lock();
288+
if (valid) {
289+
if (cancel) event->cancel();
290+
else event->notify(time);
291+
}
292+
valid=false;
293+
mutex.unlock();
294+
}
295+
296+
public:
297+
void pending_notify(sc_time t) {
298+
mutex.lock();
299+
time=t;
300+
valid=true;
301+
mutex.unlock();
302+
sc_core::sc_register_stage_callback(*this, sc_core::SC_POST_UPDATE);
303+
}
304+
void pending_cancel() {
305+
mutex.lock();
306+
valid=true;
307+
cancel=true;
308+
mutex.unlock();
309+
sc_core::sc_register_stage_callback(*this, sc_core::SC_POST_UPDATE);
310+
}
311+
312+
};
313+
pending_helper async_helper;
276314
public:
277315

278316
sc_event();

0 commit comments

Comments
 (0)