Skip to content

WIP: Parallel SystemC Module #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions src/sysc/communication/sc_prim_channel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ sc_prim_channel::sc_prim_channel( const char* name_ )
m_registry->insert( *this );
}

sc_prim_channel::sc_prim_channel( bool is_kernel )
: sc_object( ),
m_registry( simcontext()->get_prim_channel_registry() ),
m_update_next_p( 0 )
{
if (is_kernel) {
m_registry->insert_internal( *this );
} else {
m_registry->insert( *this );
}
}

// destructor

Expand Down Expand Up @@ -237,18 +248,8 @@ class sc_prim_channel_registry::async_update_list
// ----------------------------------------------------------------------------

void
sc_prim_channel_registry::insert( sc_prim_channel& prim_channel_ )
sc_prim_channel_registry::insert_internal( sc_prim_channel& prim_channel_ )
{
if( sc_is_running() ) {
SC_REPORT_ERROR( SC_ID_INSERT_PRIM_CHANNEL_, "simulation running" );
return;
}

if( m_simc->elaboration_done() ) {
SC_REPORT_ERROR( SC_ID_INSERT_PRIM_CHANNEL_, "elaboration done" );
return;
}

#ifdef DEBUG_SYSTEMC
// check if prim_channel_ is already inserted
for( int i = 0; i < size(); ++ i ) {
Expand All @@ -264,6 +265,21 @@ sc_prim_channel_registry::insert( sc_prim_channel& prim_channel_ )

}

void
sc_prim_channel_registry::insert( sc_prim_channel& prim_channel_ )
{
if( sc_is_running() ) {
SC_REPORT_ERROR( SC_ID_INSERT_PRIM_CHANNEL_, "simulation running" );
return;
}

if( m_simc->elaboration_done() ) {
SC_REPORT_ERROR( SC_ID_INSERT_PRIM_CHANNEL_, "elaboration done" );
return;
}
insert_internal( prim_channel_ );
}

void
sc_prim_channel_registry::remove( sc_prim_channel& prim_channel_ )
{
Expand Down
3 changes: 3 additions & 0 deletions src/sysc/communication/sc_prim_channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class SC_API sc_prim_channel
// constructors
sc_prim_channel();
explicit sc_prim_channel( const char* );
explicit sc_prim_channel( bool );

// destructor
virtual ~sc_prim_channel();
Expand Down Expand Up @@ -229,7 +230,9 @@ class SC_API sc_prim_channel
class sc_prim_channel_registry
{
friend class sc_simcontext;
friend class sc_prim_channel;

void insert_internal( sc_prim_channel& );
public:

void insert( sc_prim_channel& );
Expand Down
27 changes: 26 additions & 1 deletion src/sysc/kernel/sc_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <cstring>

#include "sysc/kernel/sc_event.h"
#include "sc_simcontext.h"
#include "sysc/kernel/sc_kernel_ids.h"
#include "sysc/kernel/sc_stage_callback_registry.h"
#include "sysc/kernel/sc_process.h"
Expand Down Expand Up @@ -61,6 +62,10 @@ sc_event::basename() const
void
sc_event::cancel()
{
if (m_simc != sc_get_curr_simcontext()) {
m_async_helper.pending_cancel();
return;
}
// cancel a delta or timed notification
switch( m_notify_type ) {
case DELTA: {
Expand All @@ -86,6 +91,10 @@ sc_event::cancel()
void
sc_event::notify()
{
if (m_simc != sc_get_curr_simcontext()) {
m_async_helper.pending_notify();
return;
}
// immediate notification
if( !m_simc->evaluation_phase() )
// coming from
Expand All @@ -103,6 +112,10 @@ sc_event::notify()
void
sc_event::notify( const sc_time& t )
{
if (m_simc != sc_get_curr_simcontext()) {
m_async_helper.pending_notify(t);
return;
}
if( m_notify_type == DELTA ) {
return;
}
Expand Down Expand Up @@ -168,6 +181,10 @@ static void sc_warn_notify_delayed()
void
sc_event::notify_delayed()
{
if (m_simc != sc_get_curr_simcontext()) {
m_async_helper.pending_notify();
return;
}
sc_warn_notify_delayed();
if( m_notify_type != NONE ) {
SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
Expand All @@ -180,6 +197,11 @@ sc_event::notify_delayed()
void
sc_event::notify_delayed( const sc_time& t )
{
if (m_simc != sc_get_curr_simcontext()) {
m_async_helper.pending_notify(t);
return;
}

sc_warn_notify_delayed();
if( m_notify_type != NONE ) {
SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
Expand Down Expand Up @@ -287,6 +309,7 @@ sc_event::sc_event( const char* name )
, m_threads_dynamic()
, m_name()
, m_parent_with_hierarchy_flag(NULL)
, m_async_helper(this)
{
register_event( name );
}
Expand All @@ -310,6 +333,7 @@ sc_event::sc_event()
, m_threads_dynamic()
, m_name()
, m_parent_with_hierarchy_flag(NULL)
, m_async_helper(this)
{
register_event( NULL );
}
Expand All @@ -333,6 +357,7 @@ sc_event::sc_event( kernel_tag, const char* name )
, m_threads_dynamic()
, m_name()
, m_parent_with_hierarchy_flag(NULL)
, m_async_helper(this)
{
register_event( name, /* is_kernel_event = */ true );
}
Expand Down Expand Up @@ -540,7 +565,7 @@ union sc_event_timed_u
char dummy[sizeof( sc_event_timed )];
};

static
thread_local static
sc_event_timed_u* free_list = 0;

void*
Expand Down
53 changes: 53 additions & 0 deletions src/sysc/kernel/sc_event.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
#include "sysc/kernel/sc_kernel_ids.h"
#include "sysc/kernel/sc_simcontext.h"
#include "sysc/communication/sc_writer_policy.h"
#include "sysc/communication/sc_prim_channel.h"
#include "sysc/utils/sc_ptr_flag.h"
#include <mutex>

#if defined(_MSC_VER) && !defined(SC_WIN_DLL_WARN)
#pragma warning(push)
Expand Down Expand Up @@ -273,6 +275,46 @@ class SC_API sc_event
friend class sc_join;
friend class sc_trace_file;

class pending_helper : public sc_prim_channel {
std::mutex mutex;
class sc_event *event;

bool cancel = false;
sc_time time;

void update(void) {
std::lock_guard<std::mutex> lg(mutex);
if (cancel) {
event->cancel();
} else {
if (time < sc_time_stamp()) {
event->notify(SC_ZERO_TIME);
} else {
event->notify(time-sc_time_stamp());
}
}
}

public:
void pending_notify(sc_time t) {
std::lock_guard<std::mutex> lg(mutex);
time = t+sc_time_stamp();
async_request_update();
}
void pending_notify() {
std::lock_guard<std::mutex> lg(mutex);
time = SC_ZERO_TIME;
async_request_update();
}
void pending_cancel() {
std::lock_guard<std::mutex> lg(mutex);
cancel = true;
async_request_update();
}

pending_helper(sc_event *e) : sc_prim_channel(true) { event = e; }
};
friend class pending_helper;
public:

sc_event();
Expand Down Expand Up @@ -354,6 +396,9 @@ class SC_API sc_event
// disabled
sc_event( const sc_event& );
sc_event& operator = ( const sc_event& );

pending_helper m_async_helper;

};

// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -424,6 +469,10 @@ inline
void
sc_event::notify_internal( const sc_time& t )
{
if (m_simc != sc_get_curr_simcontext()) {
m_async_helper.pending_notify(t);
return;
}
if( t == SC_ZERO_TIME ) {
// add this event to the delta events set
m_delta_event_index = m_simc->add_delta_event( this );
Expand All @@ -441,6 +490,10 @@ inline
void
sc_event::notify_next_delta()
{
if (m_simc != sc_get_curr_simcontext()) {
m_async_helper.pending_notify(SC_ZERO_TIME);
return;
}
if( m_notify_type != NONE ) {
SC_REPORT_ERROR( SC_ID_NOTIFY_DELAYED_, 0 );
}
Expand Down
2 changes: 2 additions & 0 deletions src/sysc/kernel/sc_name_gen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ sc_name_gen::sc_name_gen() : m_unique_name_map(), m_unique_name()

sc_name_gen::~sc_name_gen()
{
std::unique_lock<std::mutex> lock(m_mutex);
sc_strhash<int*>::iterator it( m_unique_name_map );
for( ; ! it.empty(); it ++ ) {
delete it.contents();
Expand All @@ -58,6 +59,7 @@ sc_name_gen::~sc_name_gen()
const char*
sc_name_gen::gen_unique_name( const char* basename_, bool preserve_first )
{
std::unique_lock<std::mutex> lock(m_mutex);
if( basename_ == 0 || *basename_ == 0 ) {
SC_REPORT_ERROR( SC_ID_GEN_UNIQUE_NAME_, 0 );
basename_ = "unnamed"; // usually not reached
Expand Down
3 changes: 2 additions & 1 deletion src/sysc/kernel/sc_name_gen.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#ifndef SC_NAME_GEN
#define SC_NAME_GEN

#include <mutex>
#include <string>
#include "sysc/utils/sc_hash.h"

Expand All @@ -52,7 +53,7 @@ class sc_name_gen
bool preserve_first = false );

private:

std::mutex m_mutex;
sc_strhash<int*> m_unique_name_map;
std::string m_unique_name;

Expand Down
16 changes: 15 additions & 1 deletion src/sysc/kernel/sc_object_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ sc_object_manager::~sc_object_manager()
// | Result is an std::string containing the name.
// +----------------------------------------------------------------------------
std::string sc_object_manager::create_name(const char* leaf_name)
{
{
std::unique_lock<std::mutex> lock(m_mutex);

bool clash; // true if path name exists in obj table
std::string leafname_string; // string containing the leaf name.
std::string parentname_string; // parent path name
Expand Down Expand Up @@ -337,6 +339,8 @@ sc_object_manager::hierarchy_size()
bool
sc_object_manager::insert_external_name(const std::string& name)
{
std::unique_lock<std::mutex> lock(m_mutex);

if(!name_exists(name)) {
m_instance_table[name].m_element_p = NULL;
m_instance_table[name].m_name_origin = SC_NAME_EXTERNAL;
Expand Down Expand Up @@ -368,6 +372,8 @@ sc_object_manager::insert_external_name(const std::string& name)
void
sc_object_manager::insert_event(const std::string& name, sc_event* event_p)
{
std::unique_lock<std::mutex> lock(m_mutex);

m_instance_table[name].m_element_p = static_cast<void*>(event_p);
m_instance_table[name].m_name_origin = SC_NAME_EVENT;
}
Expand All @@ -385,6 +391,8 @@ sc_object_manager::insert_event(const std::string& name, sc_event* event_p)
void
sc_object_manager::insert_object(const std::string& name, sc_object* object_p)
{
std::unique_lock<std::mutex> lock(m_mutex);

m_instance_table[name].m_element_p = static_cast<void*>(object_p);
m_instance_table[name].m_name_origin = SC_NAME_OBJECT;
}
Expand Down Expand Up @@ -479,6 +487,8 @@ sc_object_manager::top_of_module_name_stack_name() const
void
sc_object_manager::remove_event(const std::string& name)
{
std::unique_lock<std::mutex> lock(m_mutex);

instance_table_t::iterator it; // instance table iterator.
it = m_instance_table.find(name);
if(it != m_instance_table.end()
Expand All @@ -501,6 +511,8 @@ sc_object_manager::remove_event(const std::string& name)
void
sc_object_manager::remove_object(const std::string& name)
{
std::unique_lock<std::mutex> lock(m_mutex);

instance_table_t::iterator it; // instance table iterator.
it = m_instance_table.find(name);
if(it != m_instance_table.end()
Expand All @@ -523,6 +535,8 @@ sc_object_manager::remove_object(const std::string& name)
bool
sc_object_manager::remove_external_name(const std::string& name)
{
std::unique_lock<std::mutex> lock(m_mutex);

instance_table_t::iterator it; // instance table iterator.
it = m_instance_table.find(name);
if(it != m_instance_table.end()
Expand Down
2 changes: 2 additions & 0 deletions src/sysc/kernel/sc_object_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#define SC_OBJECT_MANAGER_H

#include <map>
#include <mutex>
#include <vector>

namespace sc_core {
Expand Down Expand Up @@ -110,6 +111,7 @@ class sc_object_manager
bool m_event_walk_ok; // true if can walk events.
instance_table_t m_instance_table; // table of instances.
sc_module_name* m_module_name_stack; // sc_module_name stack.
std::mutex m_mutex; // Mutex to ensure thread safety.
instance_table_t::iterator m_object_it; // object instance iterator.
object_vector_t m_object_stack; // sc_object stack.
bool m_object_walk_ok; // true if can walk objects.
Expand Down
6 changes: 3 additions & 3 deletions src/sysc/kernel/sc_process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ namespace sc_core {
// Note the special name for 'non_event' - this makes sure it does not
// appear as a named event.

std::vector<sc_event*> sc_process_handle::empty_event_vector;
std::vector<sc_object*> sc_process_handle::empty_object_vector;
thread_local std::vector<sc_event*> sc_process_handle::empty_event_vector;
thread_local std::vector<sc_object*> sc_process_handle::empty_object_vector;
sc_event& sc_process_handle::non_event() { return sc_get_curr_simcontext()->null_event(); }

// Last process that was created:

sc_process_b* sc_process_b::m_last_created_process_p = 0;
thread_local sc_process_b* sc_process_b::m_last_created_process_p = 0;

//------------------------------------------------------------------------------
//"sc_process_b::add_static_event"
Expand Down
Loading
Loading