|
Boost : |
From: Branko Èibej (branko.cibej_at_[hidden])
Date: 2000-08-24 03:56:39
William Kempf wrote:
>
> --- In boost_at_[hidden], Jens Maurer <Jens.Maurer_at_g...> wrote:
> > - Implement generic debugging aids, if possible. For example, a
> > mutex deadlock detection is a must.
>
> Yep. Though I'm not the one to tell you how this can be done ;).
It's relatively straight-forward, although it's a bit tricky to implement
the check efficiently. Each thread needs to have a list of mutexes it
currently owns, and which mutex (if any) it's waiting for; a mutex needs
to know its current owner. Then, before a thread starts waiting on a
mutex, it (recursively) checks whether the owner of the mutex is
waiting on one of the mutexes the thread owns.
Something like this:
struct thread;
struct mutex {
//...
thread* owner;
void lock();
void unlock();
};
struct thread {
//...
mutex* waiting_for;
std::set<mutex*> owned;
};
bool would_deadlock (mutex* m, thread* t)
{
while (m->owner != NULL)
{
if (t->owned.end() != t->owned.find(m->owner->waiting_for))
return true;
m = m->owner->waiting_for;
}
return false;
}
void mutex::lock()
{
thread* t = current_thread();
while (owner != NULL)
{
if (would_deadlock(this, t))
{
t->waiting_for = NULL;
throw deadlock;
}
t->waiting_for = this;
// Sleep until mutex is unlocked
}
t->waiting_for = NULL;
t->owned.insert(this);
owner = t;
}
void mutex::unlock()
{
owner->owned.erase(this);
owner = NULL;
// Wake waiting threads
}
Of course, the interesting bit is that all of mutex::lock must be
atomic, otherwise you've got a race condition.
Brane
-- Branko Èibej <branko.cibej_at_[hidden]> HERMES SoftLab, Litijska 51, 1000 Ljubljana, Slovenia voice: (+386 1) 586 53 49 fax: (+386 1) 586 52 70
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk