BURTON Mark
Builds for 1 pipeline failed in 31 minutes 18 seconds

force round-robin for determinism

... ... @@ -58,7 +58,8 @@
#include "greenthreads/util.h"
#include "greenthreads/async_event.h"
#define COUT if (0) cout << pthread_self() << ":"
#define COUT if (0) cout << sc_time_stamp() << ":"
//<< pthread_self() << ":"
namespace gs {
namespace gt {
... ... @@ -83,7 +84,7 @@ public:
private:
std::list<source_entry> sources;
cond_mutex start_mutex;
std::list<source_entry>::iterator start_source;
std::list<source_entry>::iterator run_source;
cond_mutex cnd_mutex;
sc_core::sc_time backWindow;
sc_core::sc_time frontWindow;
... ... @@ -91,8 +92,6 @@ private:
bool sc_is_back_window;
int active;
async_event checkWindowEvent;
bool have_d_mutex;
fifo_mutex d_mutex;
public:
void unlock() {
... ... @@ -117,11 +116,10 @@ public:
, sc_behind_mode("sc_behind",false)
, sources()
, start_mutex()
, start_source(sources.begin())
, run_source(sources.end())
, cnd_mutex()
, backWindow(SC_ZERO_TIME), frontWindow(SC_ZERO_TIME), sc_is_back_window(false)
, active(0)
, d_mutex()
{
/* Prevent sc_stop posting an invisible event (causing us to hang) */
sc_core::sc_set_stop_mode(SC_STOP_IMMEDIATE);
... ... @@ -129,16 +127,6 @@ public:
SC_METHOD(checkWindow);
sensitive << checkWindowEvent;
dont_initialize();
have_d_mutex=false;
/* deterministic value here will always be the default value (lua file not parsed yet) */
}
void end_of_elaboration() {
if (deterministic) {
d_mutex.lock();
have_d_mutex=true;
}
}
void start_of_simulation() {
... ... @@ -146,19 +134,12 @@ public:
* Need to wait till start of simulation to start the window,
* because otherwise the quantum may not be set.
*/
checkWindowEvent.notify(tlm_utils::tlm_quantumkeeper::get_global_quantum());
// COUT << " quantum " << tlm_utils::tlm_quantumkeeper::get_global_quantum() << "\n";
start_source=sources.begin();
start_mutex.broadcast();
// checkWindowEvent.notify(tlm_utils::tlm_quantumkeeper::get_global_quantum());
checkWindowEvent.notify();
COUT << " quantum " << tlm_utils::tlm_quantumkeeper::get_global_quantum() << "\n";
}
~centralSyncPolicy() {
/* release other models */
if (have_d_mutex) {
d_mutex.unlock();
have_d_mutex=false;
}
/*
* Take the lock before you exit, will force others out of the critical region
* (preventing segfault on exit)
... ... @@ -186,17 +167,15 @@ public:
return; // do not attempt to sync this source.
}
if (deterministic) {
if (t > (backWindow + source->quantum)) {
if (source->locked) {
source->locked = false;
d_mutex.unlock();
}
}
}
/* wait if we're ahead the backWindow plus a quantum */
while (t > (backWindow + source->quantum)) {
if (deterministic) {
if (&(*run_source) == source) {
runNext(); // go to the next source
checkWindowEvent.notify(); // give SystemC a kick
cnd_mutex.broadcast();
}
}
int p = cnd_mutex.timedwait();
if ( p != 0 ) {
SC_REPORT_ERROR("greenthreads", "Deadlock timeout reached");
... ... @@ -206,10 +185,8 @@ public:
cnd_mutex.unlock();
if (deterministic) {
if (!source->locked) {
d_mutex.lock();
source->locked=true;
}
// Check we have the token
checkRunning(source);
}
}
... ... @@ -227,17 +204,32 @@ public:
return entry;
}
/* ensure that the start of simulation is deterministic
/* deterministic round-robbin
*/
void startRunning(source_entry *source)
void checkRunning(source_entry *source)
{
start_mutex.lock();
while(&(*start_source) != source) {
while(&(*run_source) != source) {
start_mutex.timedwait();
}
start_source++;
COUT << "Running "<< source->name<<" @ "<<source->end_time<<"\n";
start_mutex.unlock();
}
void runNext()
{
start_mutex.lock();
COUT << "Now stopped "<< (*run_source).name<<" @ "<<(*run_source).end_time<<"\n";
run_source++;
start_mutex.broadcast();
start_mutex.unlock();
}
void startRun()
{
start_mutex.lock();
run_source=sources.begin();
COUT << "Start "<< (*run_source).name<<" @ "<<(*run_source).end_time<<"\n";
start_mutex.broadcast();
start_mutex.unlock();
start_mutex.broadcast_l();
}
/*
... ... @@ -249,12 +241,6 @@ public:
*/
void checkWindow()
{
// We may have been woken up to do somethign on behalf of a Qemu.
if (have_d_mutex) {
d_mutex.unlock();
have_d_mutex=false;
}
cnd_mutex.lock();
if (sc_is_back_window) {
update_window();
... ... @@ -262,19 +248,31 @@ public:
sc_core::sc_time sc_front_window=(sc_behind_mode)?backSourceWindow:frontWindow;
// or backWindow+quantum
if (sc_time_stamp() < sc_front_window) {
// Begining of our quantum !
if (deterministic) {
if (d_mutex.trylock()) {
/* otherwise a sync source has it, and we will be called again */
if (run_source==sources.end()) {
/* we have the right to run
* otherwise a sync source has it, and we will be called
* again.
*/
checkWindowEvent.notify(sc_front_window - sc_time_stamp());
have_d_mutex=true;
COUT << "Now running SystemC\n";
}
} else {
checkWindowEvent.notify(sc_front_window - sc_time_stamp());
}
} else {
// End of our quantum !
/* Ensure there are no pending token requests. */
if (active==0) {
if (deterministic) {
if (run_source==sources.end()) {
COUT << "Stoppping SystemC\n";
startRun();
}
}
int p = cnd_mutex.timedwait();
if ( p != 0 ) {
SC_REPORT_ERROR("greenthreads", "Deadlock timeout reached");
... ... @@ -332,12 +330,14 @@ class syncSource {
source_entry *handle;
pthread_t sc_thread;
const char* name;
bool running=false;
sc_event quantumEvent;
public:
SC_HAS_PROCESS(syncSource);
/*
* This class MUST be instanciated from SystemC (and in the SystemC thread)
*/
syncSource(const char* _name, uint64_t quantum, bool _decoupled = false):name(_name) {
syncSource(const char* _name, uint64_t quantum, bool _decoupled = false):name(_name) {
sc_thread = pthread_self();
handle = centralSyncPolicy::share.registerSource(name, this, quantum);
centralSyncPolicy::share.initWindow(SC_ZERO_TIME, handle, _decoupled);
... ... @@ -347,10 +347,6 @@ syncSource(const char* _name, uint64_t quantum, bool _decoupled = false):name(_n
if (pthread_equal(pthread_self(), sc_thread)) {
return;
}
if (!running) {
centralSyncPolicy::share.startRunning(handle);
running=true;
}
// COUT << "Sync "<<name<<" At sc_time:"<<sc_time_stamp()<< " sync time:"<<t<<"\n";
centralSyncPolicy::share.setWindow(t, handle);
}
... ...
... ... @@ -101,12 +101,6 @@ public:
{
pthread_cond_broadcast(&cnd);
}
void broadcast_l()
{
lock();
broadcast();
unlock();
}
};
/** Convenience fifo mutex (diterministic) */
... ...