Sign in to follow this  

ThreadLock

This topic is 3300 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This class is inherited by any other class to make it thread-safe. I was wondering how thread-safe this code really is. Any help is appreciated.
class ThreadLock
{
  volatile bool locked_;

public:
  // unlocked upon instantiation
  ThreadLock()
  {
    locked_ = false;
  }

  // waits for a turn and locks the object
  void Lock()
  {
    while( locked_ );
    locked_ = true;
  }

  // returns true on success, or false on timeout
  bool Lock( double timeout )
  {
    clock_t timeout2 = clock_t( timeout * CLOCKS_PER_SEC );
    clock_t start = ::clock();

    while( locked_ )
      if( ::clock() - start > timeout2 )
        return false;

    locked_ = true;
    return true;
  }

  // unlocks the object
  void Unlock()
  {
    locked_ = false;
  }

  // returns the status of the lock
  bool IsLocked() const
  {
    return locked_;
  }
};

Share this post


Link to post
Share on other sites
Quote:
I was wondering how thread-safe this code really is.


I don't believe it's possible to safely implement spinlock without xchg of sorts.

In following case, multiple threads can acquire the lock on context switch.
while( locked_ )
if( ::clock() - start > timeout2 )
return false;
// context switch
locked_ = true;
return true;


Another problem is that for single core CPUs the while loops would need to have Sleep(x) in them, or the wait loop may prevent other threads from progressing. While it shouldn't be a problem in general, reading a volatile variable may also stress the memory bus, but that's hardware specific.

At very least, the code of lock should be:
int lock_value;
...
int new_value = 1;
while (exchange(lock_value, new_value) != 0) Sleep(x);
Where exchange is the appropriate atomic exchange operation.

X is also problematic, since the value could be 0 on 1, depending on how scheduler would handle value of 0 - it depends whether it schedules a different thread.

Share this post


Link to post
Share on other sites

void Lock()
{
while( locked_ );
locked_ = true;
}

1. Thread locks the object
2. Two other threads are spinning in the while loop
3. First thread unlocks
4. Second thread drops out of the loop
5. OS context switches to the third thread before setting locked to true
6. Third thread drops out of the loop
7. Both threads think they've locked the object

I'm not even going to start on what exactly "volatile" means in this context or what will happen with processors that play fast&loose with cache coherency.

Syncronization primitives are much harder than they look. Your OS will have some written already. Prefer to use those.

Share this post


Link to post
Share on other sites
A quick repeat From Here.


//------------------------------------------------------------------------
class Mutex
{
public:
Mutex()
{
InitializeCriticalSection(&m_mutex);
}
~Mutex()
{
DeleteCriticalSection(&m_mutex);
}
void Acquire()
{
EnterCriticalSection(&m_mutex);
}
void Release()
{
LeaveCriticalSection(&m_mutex);
}

private:
CRITICAL_SECTION m_mutex;
}

//------------------------------------------------------------------------
// A Lock provides a safe way to acquire and release a Mutex. The Mutex
// is acquired when the Lock it created. The Mutex is released when the
// Lock goes out of scope.
//------------------------------------------------------------------------
class Lock
{
public:
Lock(Mutex &mutex) : m_mutex(mutex) {m_mutex.Acquire();}
~Lock() {m_mutex.Release();}
const Lock &operator = ( const Lock &l ) { l; return *this; }

private:
Mutex &m_mutex;
}

Share this post


Link to post
Share on other sites

This topic is 3300 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this