Short answer:
Threading libraries, be they user-level threads (lighter and faster for context switching ) or kernel-level threads, are not used to provide real concurrency. Rather, they are used to implement coroutine semantics of SC_THREAD
processes.
Long answer:
SystemC has 3 types of processes (i.e., units of concurrency), the most important of which are only two:
SC_METHOD
s are methods (similar to always
statements in Verilog) that
execute in their entirety in zero time when triggered by an event. They cannot
use wait
to wait for a time interval or event occurrence.
SC_THREAD
s are methods (like initial
statements in Verilog) that
execute only once, but they can use wait
to wait for particular
events or periods of time, and can use loops to emulate always
statements (so an SC_THREAD
can consume time).
For an implementation perspective, there is no problem with SC_METHOD
s because they are just like methods registered with the SystemC kernel to be called when triggered. However, for SC_THREAD
s, although they are defined as member functions, their behavior is not like ordinary routines. They are called coroutines:
Subroutines that allow multiple entry points for suspending and resuming execution at certain locations.
The SystemC kernel doesn't furnish real concurrency for system-level or RTL models. It only offers simulated concurrency through the process construct. Therefore, when writing high-level models, you don't have to use synchronization primitives (e.g., locks or semaphores) to protect data shared by different processes, since at any one time, only one process is executing and it cannot be aborted by the SystemC kernel (execution switches to the next process ready to execute only when the currently executing process relinquishes control. Still synchronization can be used, but SystemC promotes the use of message passing in channels for communication among processes. This is an advantage, since it reduces complexity. However, there are disadvantages too. SystemC models execute sequentially (not parallelized) so they don't utilize multicore architectures to speed up simulations. This is a hot research area where simulation performance is desired.
Anyway, the SystemC kernel thus implements cooperative scheduling, where each SC_THREAD
willingly relinquishes control (by using wait
) to allow other SC_THREAD
processes to execute. If you have an infinite loop inside an SC_THREAD
process that never relinquishes control, the whole simulation will be stuck there and simulation time won't advance. The same is true about SC_METHOD
s, which must return for the SystemC kernel to regain control.
In order to implement that cooperative scheduling strategy using coroutines, a threading library is used (e.g., pthreads, or QuickThread which is included in the SystemC source code) to enable SC_THREAD
's (launched as threads) to suspend themselves and enable the kernel to resume them later. Read this article to know more about this.