From 91108bb2858306684c8a721271367b85d6d401aa Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 31 Oct 2008 17:10:06 -0700 Subject: [PATCH] lockdep: include Mutex.cc --- src/common/Mutex.cc | 123 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 src/common/Mutex.cc diff --git a/src/common/Mutex.cc b/src/common/Mutex.cc new file mode 100644 index 0000000000000..7cd254a6e0b26 --- /dev/null +++ b/src/common/Mutex.cc @@ -0,0 +1,123 @@ + +#include "Mutex.h" + +int g_lockdep = 0; + +#ifdef LOCKDEP + +#include "include/types.h" +#include "Clock.h" +#include "BackTrace.h" + +#include + +#include "config.h" + +#define dout(l) if (l<=g_conf.debug_lockdep) *_dout << g_clock.now() << " " << pthread_self() << " lockdep: " +#define derr(l) if (l<=g_conf.debug_lockdep) *_derr << g_clock.now() << " " << pthread_self() << " lockdep: " + + +pthread_mutex_t lockdep_mutex = PTHREAD_MUTEX_INITIALIZER; + +hash_map > held; +hash_map > follows; // follows +hash_map > follows_ever; + +#define BACKTRACE_SKIP 3 + +// does a follow b? +bool does_follow(const char *a, const char *b) +{ + if (!follows.count(a)) + return false; + + map &s = follows[a]; + if (s.count(b)) { + dout(0) << "------------------------------------" << std::endl; + dout(0) << a << " <- " << b << " at: " << std::endl; + s[b]->print(*_dout); + *_dout << std::endl; + return true; + } + + for (map::iterator p = s.begin(); p != s.end(); p++) + if (does_follow(p->first, b)) { + dout(0) << a << " <- " << p->first << " at: " << std::endl; + p->second->print(*_dout); + *_dout << std::endl; + return true; + } + + return false; +} + +void Mutex::_will_lock() +{ + pthread_t p = pthread_self(); + + dout(20) << name << " _will_lock" << std::endl; + + pthread_mutex_lock(&lockdep_mutex); + + // check dependency graph + map &m = held[p]; + for (map::iterator p = m.begin(); + p != m.end(); + p++) { + if (!follows[name].count(p->first)) { + // new dependency + + // did we just create a cycle? + BackTrace *bt = new BackTrace(BACKTRACE_SKIP); + if (does_follow(p->first, name)) { + dout(0) << "new dependency " << name << " <- " << p->first + << " creates a cycle at" + << std::endl; + bt->print(*_dout); + *_dout << std::endl; + *_dout << std::endl; + *_dout << std::endl; + + // don't add this dependency, or we'll get aMutex. cycle in the graph, and + // does_follow() won't terminate. + } else { + follows[name][p->first] = bt; + dout(10) << name << " <- " << p->first << " at" << std::endl; + //bt->print(*_dout); + } + } + } + + pthread_mutex_unlock(&lockdep_mutex); +} + +void Mutex::_locked() +{ + BackTrace *bt = new BackTrace(BACKTRACE_SKIP); + pthread_t p = pthread_self(); + + dout(20) << name << " _locked" << std::endl; + + pthread_mutex_lock(&lockdep_mutex); + held[p][name] = bt; + pthread_mutex_unlock(&lockdep_mutex); +} + +void Mutex::_unlocked() +{ + pthread_t p = pthread_self(); + + dout(20) << name << " _unlocked" << std::endl; + pthread_mutex_lock(&lockdep_mutex); + assert(held.count(p)); + assert(held[p].count(name)); + delete held[p][name]; + held[p].erase(name); + pthread_mutex_unlock(&lockdep_mutex); +} + + + + + +#endif -- 2.39.5