Jump to content

Cannot notify an event from pthread to SystemC process


DS1701

Recommended Posts

Hi all,

I'm trying to build source code using pthread and SystemC ( SystemC build as quickThread)

Step 1 : Create pthread

tmodule->threadID[i] = i;
result_code = pthread_create(&tmodule->thread[i], NULL, perform_func, (void*)tmodule);

Step 2 : Kick a thread to wait event

void wait_thread() {
		while (1) {
			wait(ev_wait);
			//wait(wait_time_val, SC_NS);
			cout << "@" << sc_time_stamp() << " :: " << "Waiting " << wait_time_val << " second." << endl;
			resume_thread();
		}
	}

In perform_func will call to 

void wait_time_func(double val) {
		wait_time_val = val;
		ev_wait.notify(SC_ZERO_TIME);
	}

Although ev_wait.notify() called but wait_thread cannot reach event. 

Could you please help me about this issue??

Note : I'm running on VS2015 windows

Thank you so much.

header.h pthread_function.c Source.cpp

Link to comment
Share on other sites

SystemC is a single-thread simulator and moreover not thread-safe  due to various reasons. The problem you are facing is that you modify datastructures in the SystemC kernel (by calling notify() ) asyncronously since you are running it in another (OS-)thread. This might work in some case but in most cases it will not. To cut a long story short you cannot use sc_event to syncronize os-threads.

But there are means to handle this case namely async_request_update(). To see an example you might check out https://stackoverflow.com/questions/49814756/async-request-update-example-in-systemc esp. the implementation of class ThreadSafeEvent.

One remark: I strongly suggest to use C++11 and there std::thread since it makes your code more readable and abstracts from the underlying API. E.g. PThread is not a native Windows thread implementation rather belongs to some POSIX layer which might introduce additional issues.

Link to comment
Share on other sites

I concur with Eyck's comments. A few more thoughts:

  1. SystemC-processes are very different from OS processes.
  2. SystemC itself runs inside a single OS-thread.
  3. SystemC uses cooperative multitasking to simulate SystemC processes, which come in three flavors: SC_THREAD, SC_METHOD, and SC_CTHREAD (for synthesis).
    • This is common among discrete event-driven simulators (e.g., Verilog, SystemVerilog, and VHDL use the same idea)
    • Cooperative multitasking simplifies the coding a lot to make it easier for designers using these simulators.
  4. When documenting, I find it useful to keep these distinctions clear. To re-iterate:
    • OS-processes and OS-threads are preemptive in nature.
    • OS-threads live within the context of OS-processes. The primary distinction being that OS-threads share common resources (primarily memory).
    • SystemC-processes live within a single OS-thread.
    • SystemC-processes are not preemptive in nature, and must yield in order to allow other processes to run (i.e., cooperate to allow the simulation to proceed).
    • The distinction between SystemC-processes is the manner in which they yield to each other:
      • SC_THREAD-processes and SC_CTHREAD-processes yield by calling sc_core::wait().
      • SC_METHOD-processes yield by returning.
  5. When communicating between SystemC and an external OS-thread, SystemC events may only be invoked from within the context of the SystemC OS-thread. To inject an event, you may devise a primitive channel using async_request_update() to inject events via the update() method.
  6. C++11 provides an OS-agnostic library to create OS-threads, which is very handy.
  7. Keep in mind that data transfers between two processes must be carefully guarded using a proper mutex (available in C++11). I suggest you use a guarded mutex.
Link to comment
Share on other sites

Thank @Eyck and @David Black for your information,

I tried with your method by change : sc_event ev_wait => ThreadSafeEvent ev_wait;

but It still not work. notify() is called but update() function isn't called.

Maybe something wrong.

note: If I use ThreadSafeEvent instead of sc_event , I can't using wait(event). Do you have another way? 

Thanks for your kind words

header.h pthread_function.c Source.cpp

Link to comment
Share on other sites

I had a look onto your code and it has several flaws:

  • your condion variable not protected against spurious and lost wakeups
  • you use one global condition variable for all threads. This is bad design...
  • your simulation runs out of events. Since the SC kernel does not see any events during the start of your thread(s), it simply shuts down the simulation. So before your thread is alive there is no simulation at all
  • diamond problem with multiple inheritance: ThreadSafeEvent inherits of sc_prim_channel and ThreadSafeEventIf where both inherit of sc_interface. So at least ThreadSafeEventIf needs to ingerit virtual.
  • Instead of dealing with pthreads you should use std::thread and friends. This eases your life quite a lot an makes things easier

Based on your example I created a working example at https://www.edaplayground.com/x/Nn9e using C++11. Make sure that in the field 'Compile Options' the option '-pthread' is given as well as c++11 or c++14 is selected

 

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...