e6daniel Posted June 5, 2017 Report Share Posted June 5, 2017 Hi! I am using this fair_mutex implementation in a SystemC application of mine. It is almost doing what it should albeit the mutex accidently slips through the odd user. I cannot spot the prblem :( Best Regards class fair_mutex : public sc_mutex { std::queue<sc_process_b *> s_queue; public: virtual int lock() { if (m_owner == sc_get_current_process_b()) return 0; s_queue.push(sc_get_current_process_b()); while (in_use()) { sc_core::wait(m_free); if (s_queue.front() == sc_get_current_process_b()) break; } m_owner = sc_get_current_process_b(); sc_core::wait(SC_ZERO_TIME); s_queue.pop(); return 0; } }; Quote Link to comment Share on other sites More sharing options...
Philipp A Hartmann Posted June 6, 2017 Report Share Posted June 6, 2017 Your current implementation still depends on the scheduling order of the simulation kernel: If the mutex is not locked, the first scheduled process will obtain the lock, irrespectively of any current or future locking attempts in the same evaluation phase. For example, if one process repeatedly tries to lock the mutex directly after releasing it, the lock will be granted, even if there are other processes already waiting: void procA() { while(true) { mtx.lock(); // do some work wait( 10, sc_core::SCNS ); mtx.unlock(); // will get the lock back again immediately! } } void procB { // ask for the lock slightly later wait( 5, sc_core::SC_NS ); // continue as procA procA(); } In order to fix it, you'll at least need to check the queue before granting the lock (untested): while (s_queue.front() != sc_get_current_process_b() || in_use()) { sc_core::wait(m_free); } That said, you should not be using the implementation-defined sc_process_b class and use sc_process_handle and sc_get_current_process_handle() instead, to be more standards-compliant. Hope that helps, Philipp Quote Link to comment Share on other sites More sharing options...
e6daniel Posted June 7, 2017 Author Report Share Posted June 7, 2017 (edited) Thank you soo much Philipp! You were absolutely correct that the implementation was not treating re-locks correctly. The below implemenation works in my scenarios "at least". I think it is a correct generic solution. class fair_mutex : public sc_mutex { std::queue<sc_process_handle> s_queue; public: virtual int lock() { if (m_owner == sc_get_current_process_handle()) return 0; s_queue.push(sc_get_current_process_handle()); while (s_queue.front() != sc_get_current_process_handle() || in_use()) { sc_core::wait(m_free); } m_owner = sc_get_current_process_handle(); s_queue.pop(); return 0; } }; Edited June 7, 2017 by e6daniel Quote Link to comment Share on other sites More sharing options...
jitu Posted September 15, 2021 Report Share Posted September 15, 2021 Can anyone explain me where is in_use() function implemented ? Quote Link to comment Share on other sites More sharing options...
Eyck Posted September 19, 2021 Report Share Posted September 19, 2021 SInce the question is already 4 years old I guess there will be now answer. If you need something like the fair mutex you might have a look at the scc::ordered_semaphore which can also be used as a mutex (with a value of one). At https://github.com/Minres/SystemC-Components/blob/main/src/sysc/scc you will find a complete implementation. 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.