Re: [LAD] Finding Deadlock causes in multithreaded C++ using gdb

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: Linux Audio Developers <linux-audio-dev@...>
Date: Sunday, February 20, 2011 - 10:46 pm

Hi Harry,

On Sun, 20 Feb 2011, Harry Van Haaren wrote:

> I'm working on a mulithreaded version of my pet project, and I've now

In addition to the excellent suggestions from other folks...
here's another approach.

In Hydrogen/Composite, there is a central, critical audio
lock.[3] For this lock, we set up a system for the central
audio lock that would "log" the line of code that last
locked the mutex. See [1] and [2]. Whenever you deadlock,
you can look at this->d->__locker to see the file and line
number where the mutex was last locked.

This solution was suggested to us by Krzysztof Foltman, and
once saved me a ton of time. Thanks, Krzysztof!

The important parts are:

/**
* Convenience macro for locking the Engine.
*/
#ifndef RIGHT_HERE
#define RIGHT_HERE __FILE__, __LINE__, __PRETTY_FUNCTION__
#endif

And:

class Engine : public EngineInterface
{
public:
//...
///////////////////////////////////////
// THE BIG LOCK
///////////////////////////////////////
/* Mutex locking and unlocking
*
* Easy usage: Use the RIGHT_HERE macro like this...
* engine->lock( RIGHT_HERE );
*
* More complex usage: The parameters file and function
* need to be pointers to null-terminated strings that are
* persistent for the entire session. This does *not*
* include the return value of std::string::c_str(), or
* QString::toLocal8Bit().data().
*
* Notes: The order of the parameters match GCC's
* implementation of the assert() macros.
*/
void lock( const char* file, unsigned int line, const char* function );
bool try_lock( const char* file, unsigned int line, const char* function );
void unlock();
//...
}

And:

void Engine::lock( const char* file, unsigned int line, const char* function )
{
d->__engine_mutex.lock();
d->__locker.file = file;
d->__locker.line = line;
d->__locker.function = function;
}

bool Engine::try_lock( const char* file, unsigned int line, const char* function )
{
bool locked = d->__engine_mutex.tryLock();
if ( ! locked ) {
// Lock not obtained
return false;
}
d->__locker.file = file;
d->__locker.line = line;
d->__locker.function = function;
return true;
}

void Engine::unlock()
{
// Leave "d->__locker" dirty.
d->__engine_mutex.unlock();
}

-gabriel

[1] http://gitorious.com/composite/composite/blobs/master/src/Tritium/Tritiu...
[2] http://gitorious.com/composite/composite/blobs/master/src/Tritium/src/En...
_______________________________________________
Linux-audio-dev mailing list
Linux-audio-dev@lists.linuxaudio.org
http://lists.linuxaudio.org/listinfo/linux-audio-dev

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[LAD] Finding Deadlock causes in multithreaded C++ using gdb, Harry Van Haaren, (Sun Feb 20, 9:12 pm)
Re: [LAD] Finding Deadlock causes in multithreaded C++ using..., Gabriel M. Beddingfield, (Sun Feb 20, 10:46 pm)