shanh Posted April 16, 2018 Report Share Posted April 16, 2018 A small example of async_request_event. It only triggers the first event and not the second one? Can anyone please explain why? #include <systemc> #include <unistd.h> #include <thread> using namespace sc_core; class ThreadSafeEventIf : public sc_interface { virtual void notify(sc_time delay = SC_ZERO_TIME) = 0; virtual const sc_event &default_event(void) const = 0; protected: virtual void update(void) = 0; }; class ThreadSafeEvent : public sc_prim_channel, public ThreadSafeEventIf { public: ThreadSafeEvent(const char *name = ""): event(name) {} void notify(sc_time delay = SC_ZERO_TIME) { this->delay = delay; async_request_update(); } const sc_event &default_event(void) const { return event; } protected: virtual void update(void) { event.notify(delay); } sc_event event; sc_time delay; }; SC_MODULE(Foo) { public: SC_CTOR(Foo) { SC_THREAD(main); SC_METHOD(eventTriggered); sensitive << event; dont_initialize(); } private: void main() { usleep(5 * 1000 * 1000); // Just for the example, event is added to pending events during this sleep wait(SC_ZERO_TIME); // Schedule (event is evaluated here) usleep(1 * 1000 * 1000); // Just for the example std::cout << "Done" << std::endl; } void eventTriggered() { std::cout << "Got event" << std::endl; std::cout << "sc_time " << sc_time_stamp() << std::endl; } public: ThreadSafeEvent event; }; void externalHostThread(void *arg, int d) { usleep(1 * 1000 * 1000); // Just for the example Foo* foo = (Foo*)(arg); foo->event.notify(sc_time(d,SC_NS)); std::cout << "Event notified from an external host thread" << std::endl; } int sc_main(int argc, char *argv[]) { Foo foo("foo"); int delay1 = 10; int delay2 = 15; std::thread t1(externalHostThread, &foo, delay1); std::thread t2(externalHostThread, &foo, delay2); sc_start(); t1.join(); t2.join(); return 0; } Quote Link to comment Share on other sites More sharing options...
David Black Posted April 16, 2018 Report Share Posted April 16, 2018 Remember that the SystemC OS thread is completely asynchronous to external threads and processes. Async_request_update() simply says to call update() once at the end of the delta cycle for a single object. So you can get multiple notifications within the same delta and only get one call-back. To keep from losing these you should setup a threadsafe mailbox/queue. Rather than just notify the event, you should also put an entry into the mailbox on each activation. Then your threadsafe update() method can see the multiple requests accurately. Quote Link to comment Share on other sites More sharing options...
Eyck Posted April 16, 2018 Report Share Posted April 16, 2018 Hi shanh, looking at the SystemC LRM: Quote 5.9.6 Multiple event notificationsA given event shall have no more than one pending notification. If function notify is called for an event that already has a notification pending, then only the notification scheduled to occur at the earliest time shall survive. The notification scheduled to occur at the later time shall be cancelled (or never be scheduled in the first place). this is what happens in your example. The event is notified while another event is pending since your 2 threads sleep for the same amount of time. You would need to guard the event notification, use 2 separate events or an event queue similar to tlm_utils::peq_with_cb_and_phase. Best regards 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.