kcai1107 Posted March 14, 2022 Report Share Posted March 14, 2022 I am using SystemC 2.3.2. To run-time configuration needs, I have to create a dynamic thread process by sc_spawn (by default), and a wait() statement works normally as in a static SC_THREAD process. However, when adding a pair of sc_mutex lock() and unlock() calls for some synchronization work, I get such a run-time error: Error: (E519) wait() is only allowed in SC_THREADs and SC_CTHREADs: in SC_METHODs use next_trigger() instead Obviously, this error message is of a misleading because the dynamic process I create is undoubtedly a thread type process and wait() works well. I read some examples where sc_mutext can be used with SC_THREADs and this is the very reason I create a dynamic thread rather than a dynamic method. Can anybody in this community let me know if I do something wrong or the SystemC 2.3.2 still does not support sc_mutex implementation inside a spawned thread process? This issue already becomes a show-stopper in my work, so I do sincerely appreciate your prompt attention and help! KC Quote Link to comment Share on other sites More sharing options...
David Black Posted March 14, 2022 Report Share Posted March 14, 2022 Without seeing your code, this is impossible to determine. Perhaps you can share on edaplayground.com Quote Link to comment Share on other sites More sharing options...
kcai1107 Posted March 14, 2022 Author Report Share Posted March 14, 2022 Hi David, Many thanks for your help! As I mentioned, the reason to put sc_mutex inside a (with sc_spawn) dynamic thread instead of dynamic method is because I see some sc_mutex examples where concurrent SC_THREADs are used. But I still prefer to spawn a dynamic method to implement sc_mutex if allowed. Hence, I am also wondering if sc_mutex could be somehow used in either static or dynamic method even though sc_mutex may implicitly contains wait statements. Back to your requirement for the code sharing, I feel like a detailed enough code segment will show you how I've implemented sc_mutex inside a dynamic thread process. This FIFO item issue is essentially of bounded buffer producer-consumer problem. The errors are originated from the sc_mutex implementation on "consumer side" inside dynamic_thread_process, and there is no complaint on sc_mutex implementation on "producer side" in fifo_item_producer() routine. The thing is that once commenting out the two lines of sc_mutex inside dynamic_thread_process the run-time errors aforementioned are all gone. The wait statement inside while loop has never a problem, so the wait() is irrelevant to the run-time error (but that run-time error message still points to it). The code segments are as follows: class network : sc_module { ... void end_of_elaboration( ) { // FIFO and mutex (to synchronize FIFO item insertion and removal) setup // NOTE: n_inits and n_targs become certain at end of elaboration fifo_mutex = new sc_mutex*[n_inits]; my_fifo = new std::deque<item_type>*[n_inits]; select_value = new int[n_inits]; for( int i = 0; i < n_inits; i++ ) { fifo_mutex[i] = new sc_mutex[n_targs]; my_fifo[i] = new std::deque<item_type>[n_targs]; select_value[i] = -1; } // Spawn a dynamic thread process (by default) per target for( int i = 0; i < n_targs; i++ ) { sc_spawn_options* opt = new sc_spawn_options; ostringstream oss; oss << "dynamic_thread_process" << i; sc_spawn( sc_bind(&network::dynamic_thread_process, this, i), oss.str().c_str(), opt ); } } ... void fifo_item_producer( item_type item ); void dynamic_thread_process( int targ ); ... int n_inits; int n_targs; // Dynamically define a 2D STL deque array and a 2D-array for sc_mutex std::deque<item_type>** my_fifo; sc_mutex** fifo_mutex; int* select_value; ... }; // The FIFO item producer that contains a critical section to be synchronized with sc_mutex mechanism void network::fifo_item_producer( item_type item ) { // Extract init and targ information from item ... //********* Beginning of protection of the item insertion with fifo_mutex *************// fifo_mutex[init][targ].lock( ); my_fifo[init][targ].push_back( item ); fifo_mutex[init][targ].unlock(); //************ End of protection of the item insertion with fifo_mutex ************// ... } // This dynamic thread process that is essentially a FIFO item consumer, also needs synchronizing with sc_mutex mechanism void network::dynamic_thread_process ( int targ ) { while( true ) { int select; item_type item; bool popped = false; for( int iters = 0; iters < n_inits; iters++ ) { select = (++select_value[targ]) % n_inits; //************ Beginning of protection of the item removal with fifo_mutex ************// // NOTE: if the next line is commented out, run-time error message is gone fifo_mutex[select][targ].lock( ); if( my_fifo[select][targ].size() ) { item = my_fifo[select][targ].front(); my_fifo[select][targ].pop_front( ); popped = true; break; } // NOTE: if the next line is commented out, run-time error message is gone fifo_mutex[select][target].unlock( ); //************ End of protection of the item removal with fifo_mutex ************// } if( popped == true ) { // process the popped item ... } wait( sc_time(10, SC_NS) ); } // end of while loop } // end of dynamic_thread_process Quote Link to comment Share on other sites More sharing options...
maehne Posted April 1, 2022 Report Share Posted April 1, 2022 @kcai1107: Thanks for sharing the code snippet. A minimal self-contained example exposing the issue would be helpful to replicate the issue on our side though -- especially if it is a real issue to be addressed in the SystemC proof-of-concept implementation. sc_mutex are derived from sc_object and therefore, it is recommended to manage a collection of such objects using sc_vector. The minimum benefit would be the possibility to give them a good (hierarchical) instance name, which would facilitate debugging. Have you tried to modify your implementation to use the non-blocking trylock() + wait in your dynamic process instead of the blocking lock() to work around the issue? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.