|
| 1 | + |
| 2 | + |
| 3 | +## Threading Utilities |
| 4 | + |
| 5 | +The library offers the following utilities |
| 6 | + |
| 7 | +# scp::scp_async_event |
| 8 | +***NB this could be considered for standardization within the SystemC kernel as sc_async_event*** |
| 9 | + |
| 10 | +An ***scp_async_event*** is identical to an sc_event except that it can be notified in a thread safe manner from a different thread. In the same way that an ***sc_event*** may be notified many times, an ***scp_async_event*** makes no guarantee about the number of times the actual event listener is notified, but does guarantee that it will at least be notified after the last time that any of the thread safe notify methods are called. |
| 11 | + |
| 12 | +The ***scp_async_event*** also can be considered as a ***sc_prim_channel***. In addition to the standard ***sc_event*** interface, the ***scp_async_event*** also provides convenience functions to attach and detach the primary channel from the SystemC kernel as a potential source of external events. |
| 13 | + |
| 14 | +*** NOTE *** |
| 15 | +An ***scp_async_event*** *MUST* be constructed on the SystemC thread. Failure to do so is an error and will have unexpected consequences. |
| 16 | + |
| 17 | +```cpp |
| 18 | +class scp_async_event : public sc_core::sc_prim_channel, public sc_core::sc_event |
| 19 | +{ |
| 20 | +public: |
| 21 | + scp_async_event(bool start_attached = true); |
| 22 | + void async_attach_suspending(); |
| 23 | + void async_detach_suspending(); |
| 24 | + void enable_attach_suspending(bool); |
| 25 | +} |
| 26 | +``` |
| 27 | +Hence ***async_attach_suspending*** shall attach the primary channel to the SystemC kernel as a potential source of external events, and will therefore prevent the SystemC kernel from exiting. See ***sc_prim_channel::async_attach_suspending***. Likewise ***async_detach_suspending*** will detach the primary channel, while ***enable_attach_suspending*** shall attach if the boolean argument is true, else it will detach the channel. |
| 28 | +
|
| 29 | +On construction by default the channel will be ***attached*** to the kernel, but this may be prevented by passing ***false*** to the constructor. |
| 30 | +
|
| 31 | +Notifications of the event from within the same thread as the SystemC kernel shall be treated identically to notifications posted to a normal ***sc_event***. When notified from a different thread the delay posted in the notification of the ***scp_async_event*** shall be respected, but there is no guarantee that the SystemC time will not have advanced by the time the event is posted within the SystemC kernel, so it is recommended that this delay not be used. From a separate thread there is no means to perform an ***immediate*** notification, this will be treated as a delta notification (with SC_ZERO_TIME). |
| 32 | +
|
| 33 | +Calling ***triggered()*** from a outside the SystemC kernel thread is an error and an SC_ERROR_REPORT will be generated. |
| 34 | +
|
| 35 | +# scp::run_on_systemc |
| 36 | +***NB The interface of this class could be considered for standardization within the SystemC kernel*** |
| 37 | +
|
| 38 | +***run_on_systemc*** provides a convenience class that can be instanced in order to provide the means to execute a ```std::function``` on the SystemC thread in a thread safe manner from another thread. |
| 39 | +
|
| 40 | +*** NOTE *** |
| 41 | +An instance of the ***run_on_systemc*** module *MUST* be constructed on the SystemC thread. Failure to do so is an error and will have unexpected consequences. |
| 42 | +
|
| 43 | +```cpp |
| 44 | +class run_on_systemc : public sc_core::sc_module |
| 45 | +{ |
| 46 | +public: |
| 47 | +
|
| 48 | + run_on_systemc() |
| 49 | +
|
| 50 | + void scp_cancel_pendings(); |
| 51 | + void scp_fork_on_systemc(std::function<void()> job_entry); |
| 52 | + bool scp_run_on_systemc(std::function<void()> job_entry, bool wait = true); |
| 53 | + bool scp_is_on_systemc() const; |
| 54 | +}; |
| 55 | +``` |
| 56 | + |
| 57 | +In order to run a job on the SystemC kernel thread, ***scp_run_on_systemc*** method should be called with an appropriate ```std::function```. The ***scp_run_on_systemc*** takes an optional argument to wait for the job to be scheduled and executed on SystemC, which defaults to true. |
| 58 | +The return status is set to ***true*** if the job has been successfully executed and completed and ***false*** if the job was canceled before it was finished. |
| 59 | + |
| 60 | +If ***run_on_systemc*** is called from within the SystemC thread, then the job is executed immediately (In this case the return status will be ***true***). |
| 61 | + |
| 62 | +The method ***scp_fork_on_systemc*** is a convenience function that calls ***scp_run_on_systemc*** with wait set to false (there is no return status as the job can not be interrupted). |
| 63 | + |
| 64 | +The method ***scp_cancel_pendings*** cancels all pending jobs. Any jobs which are queue'd waiting to be processed by SystemC will be canceled. |
| 65 | + |
| 66 | + |
| 67 | +# keep_alive |
| 68 | +This is a simple ***sc_module*** convenience class which contains an ***scp_async_event*** initialised to attach to the SystemC kernel, and shall therefore ensure that the simulation does not finish. The module provides a convenience function (***finish()***) to detach the event (and therefore allow the simulation to exit). |
| 69 | + |
| 70 | +```cpp |
| 71 | +class keep_alive : public sc_core::sc_module |
| 72 | +{ |
| 73 | +public: |
| 74 | + scp::async_event keep_alive_event; |
| 75 | + |
| 76 | + keep_alive(sc_core::sc_module_name name): sc_core::sc_module(name) { |
| 77 | + keep_alive_event.async_attach_suspending(); |
| 78 | + } |
| 79 | + void finish() { |
| 80 | + keep_alive_event.async_detach_suspending(); |
| 81 | + keep_alive_event.notify(); |
| 82 | + } |
| 83 | + ~keep_alive() {} |
| 84 | +}; |
| 85 | +``` |
| 86 | +
|
| 87 | +
|
| 88 | +
|
| 89 | +# realtimelimiter |
| 90 | +An instance of this sc_module will ensure that SystemC time never advances more than realtime (with a granularity of 100ms). Convenience functions to `enable` and `disable` this behavior are provided. |
| 91 | +
|
| 92 | +```cpp |
| 93 | +SC_MODULE (real_time_limiter) { |
| 94 | +public: |
| 95 | + void enable(); |
| 96 | + void disable(); |
| 97 | + real_time_limiter(const sc_core::sc_module_name& name, |
| 98 | + bool autostart = true, |
| 99 | + sc_core::sc_time accuracy=sc_core::sc_time(100, sc_core::SC_MS)): |
| 100 | +}; |
| 101 | +``` |
| 102 | + |
| 103 | +The constructor, and ***enable*** and ***disable*** funtions must be called from the systemc thread. By default, the ****real_time_limiter*** is constructed to start automatically, with an accuracy of 100ms. |
0 commit comments