I have the following code which replicates the windows manual and auto reset events.
class event
{
public:
event( bool signalled = false, bool ar = true ) :
_auto( ar ),
_signalled( signalled )
{
pthread_mutex_init( &_mutex, NULL );
pthread_cond_init( &_cond, NULL );
}
~event()
{
pthread_cond_destroy( &_cond );
pthread_mutex_destroy( &_mutex );
}
void set()
{
pthread_mutex_lock( &_mutex );
// only set and signal if we are unset
if ( _signalled == false )
{
_signalled = true;
pthread_cond_signal( &_cond );
}
pthread_mutex_unlock( &_mutex );
}
void wait()
{
pthread_mutex_lock( &_mutex );
while ( _signalled == false )
{
pthread_cond_wait( &_cond, &_mutex );
}
// if we're an autoreset event, auto reset
if ( _auto )
{
_signalled = false;
}
pthread_mutex_unlock( &_mutex );
}
void reset()
{
pthread_mutex_lock( &_mutex );
_signalled = false;
pthread_mutex_unlock( &_mutex );
}
private:
pthread_mutex_t _mutex;
pthread_cond_t _cond;
bool _signalled;
bool _auto;
};
My question surrounds the "optimisation" I've put in place in the set() method where I only call pthread_cond_signal() if the event was unsignalled. Is this a valid optimisation or have I introduced some subtle flaw by doing so.
There's definitely a difference in behavior due to that "optimization" if multiple threads are waiting for the same event. Consider this sequence of events (manual reset mode):
thread 1 - wait
thread 2 - wait
thread 3 - wait
thread 4 - set
thread 4 - set
thread 4 - set
thread 4 - reset
With your code, pthread_cond_signal will only be called once (unblocking one of threads 1-3); without the optimization it would be called 3 times (unblocking all 3 of them).
I don't know if that's a "flaw" or not, because I don't know the precise semantics of the Windows API you're emulating.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With