How to Assert If a Std::Mutex Is Locked

How to assert if a std::mutex is locked?

std::unique_lock<L> has owns_lock member function (equivalent of is_locked as you say).

std::mutex gmtx;
std::unique_lock<std::mutex> glock(gmtx, std::defer_lock);

void alpha(void) {
std::lock_guard<decltype(glock)> g(glock);
beta(void);
// some other work
}
void beta(void) {
assert(glock.owns_lock()); // or just assert(glock);
// some real work
}

EDIT: In this solution, all lock operations should be performed via unique_lock glock not 'raw' mutex gmtx. For example, alpha member function is rewritten with lock_guard<unique_lock<mutex>> (or simply lock_guard<decltype(glock)>).

How to atomically check if mutex is locked?

You can momentarily lock the lock and get the desired Thread02:

// Thread02
std::unique_lock{mutex};
// mutex isn’t locked

Check to see if Thread has already locked mutex before locking

If you're using a specific platform (Win32?) mutex implementation - then you should consult that platform's documentation.

If you're using C++11 standard mutex - std::mutex, switch to std::recursive_mutex instead. Note that you'll need to call unlock() for each call to lock().

Ensuring that current thread holds a lock on a C++11 mutex

The way I would recommend doing this is to have the functions that can only be called while holding the mutex take a reference to a std::unique_lock or std::lock_guard. In the case of unique_lock you probably also want to assert that it actually holds the lock.

This will leverage the compiler to enforce your requirements.

Presumably these functions are internal / private to your class, and you have user-facing functions that acquire the lock and then call these ones. If so, having an additional argument won't pollute the user facing API.

Something along these lines:

// public
void A::public_function() {
std::lock_guard<std::mutex> l(m_mutex);
// ... do stuff
b(l);
// ... do more stuff
}

// private
void A::b(std::lock_guard const& l) {
// ... do stuff that requires holding the mutex
}

If you need to use unique_lock instead, simply assert that l.owns_lock() is true in your function (in case you want to throw an exception).

My experience with recursive mutexes is that they make it easy to not take your lock strategy and ownership as serious as it deserves. And that they can end up biting you later. See this post.

Conditionally acquire an std::mutex

It is actually unsafe to have a unique_lock accessible from multiple threads at the same time. I'm not familiar with the opencv portion of your question, so this answer is focused on the mutex/lock usage.

static std::mutex s_FAST_GPU_mutex;
{
// Create a unique lock, attempting to acquire
std::unique_lock<std::mutex> guard(s_FAST_GPU_mutex, std::try_to_lock);
if (guard.owns_lock())
{
cv::gpu::FAST_GPU(/*params*/)(/*parameters*/);
guard.unlock(); // Or just let it go out of scope later
}
else
{
cv::FAST(/*parameters*/);
}
}

This attempts to acquire the lock, if it succeeds, uses FAST_GPU, and then releases the lock. If the lock was already acquired, then goes down the second branch, invoking FAST

Possible to check mutex is locked before calling pthread_cond_wait()?

If you create the mutex as an error-checking mutex, using:

pthread_mutexattr_t attr;
pthread_mutex_t errchkmutex;

pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&errchkmutex, &attr);

...then pthread_cond_wait() will return EPERM if the mutex is not locked by the calling thread.

(of course you would add error-checking to that mutex initialisation code).

I think error-checking mutexes are exactly the kind of "debugging mode" that you're looking for.



Related Topics



Leave a reply



Submit