SystemC-sc_mutex
学习过操作系统的人都知道,互斥(mutex)是用来保护共享资源的,以避免多个进程同时读写共享资源,导致系统行为的不确定性。互斥具有锁定和非锁定两种状态。如果有进程需要使用由互斥保护的资源,而这时互斥没有被锁定,则该进程就可以将互斥锁定,这时它就可以唯一的获得由该互斥保护的资源,并允许对资源进行任何的合法操作。当互斥已经由另外的进程锁定,这时申请互斥的进程就会被阻塞,直到锁定互斥的进程将互斥解锁。
作为一个通道,互斥实现的接口为sc_mutex_if,如下面的代码:
- class sc_mutex_if: virtual publ sc_interface
- {
- public:
- // the classical operations: k(), trylock(), and unlock()
- // blocks until mutex could be locked
- virtual int lock() = 0;
- // returns -1 if mutex could not be locked
- virtual int trylock() = 0;
- // returns -1 if mutex was not locked by caller
- virtual int unlock() = 0;
- protected:
- // constructor
- sc_mutex_if() {}
- private:
- // db
- sc_mutex_if( const sc_mutex_if& );
- sc_mutex_if& operator = ( const sc_mutex_if& );
- };
通过lock()进程可以锁定互斥,如果互斥已经被锁定,这时申请锁定的进程就被阻塞直到互斥被解锁。通过trylock()进程可以查询互斥是否被锁定,以决定是否使用lock()锁定互斥从而避免进程被阻塞。通过unlock()函数进程可以解锁互斥。
Syst2.2对sc_mutex的实现如下面的代码:
- class sc_mutex: public sc_mutex_if, public sc_prim_channel
- {
- public:
- // constructors
- sc_mutex();
- explicit sc_mutex( const char* name_ );
- // interface methods
- // blocks until mutex could be locked
- virtual int lock();
- // returns -1 if mutex could not be locked
- virtual int trylock();
- // returns -1 if mutex was not locked by caller
- virtual int unlock();
- static const char* const kind_string;
- virtual const char* kind() const
- { return kind_string; }
- protected:
- // support methods
- bool in_use() const { return ( m_owner != 0 ); }
- protected:
- sc_process_b* m_owner;
- sc_event m_free;
- private:
- // disabled
- sc_mutex( const sc_mutex& ); sc_mutex& operator = ( const sc_mutex& );
- };
- sc_mutex::sc_mutex()
- : sc_prim_channel( sc_gen_unique_name( "mutex" ) ), m_owner( 0 ){}
- sc_mutex::sc_mutex( const char* name_ ): sc_prim_channel( name_ ), m_owner( 0 ){}
- // interface methods
- // blocks until mutex could be locked
- int sc_mutex::lock(){
- while( in_use() ) { wait( m_free ); }
- m_owner = sc_get_curr_process_handle();
- return 0;
- }
- // returns -1 if mutex could not be locked
- int sc_mutex::trylock(){
- if( in_use() ) { return -1; }
- m_owner = sc_get_curr_process_handle();
- return 0;
- }
- // returns -1 if mutex was not locked by caller
- int sc_mutex::unlock()
- { if( m_owner != sc_get_curr_process_handle() ) { return -1; }
- m_owner = 0;
- m_free.notify();
- return 0;
- }
我们在前面章节曾经给出过ss_mutex的一个例子,这里不再给出。