diff options
Diffstat (limited to 'libs/pbd3/pbd/lockmonitor.h')
-rw-r--r-- | libs/pbd3/pbd/lockmonitor.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/libs/pbd3/pbd/lockmonitor.h b/libs/pbd3/pbd/lockmonitor.h new file mode 100644 index 0000000000..8fad66f83e --- /dev/null +++ b/libs/pbd3/pbd/lockmonitor.h @@ -0,0 +1,194 @@ +/* + Copyright (C) 2000 Paul Davis + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + $Id$ +*/ + +#ifndef __pbd_lockmonitor_h__ +#define __pbd_lockmonitor_h__ + +#include <pthread.h> +#include <pbd/pthread_spinlock.h> + +#undef DEBUG_LOCK_MONITOR + +#ifdef DEBUG_LOCK_MONITOR +#include <iostream> +#include <ardour/cycles.h> +#endif + +namespace PBD +{ +class Lock { + public: + Lock() { pthread_mutex_init (&_mutex, 0); } + virtual ~Lock() {} + + virtual int lock () { return pthread_mutex_lock (&_mutex); } + virtual int unlock() { return pthread_mutex_unlock (&_mutex); } + + pthread_mutex_t *mutex() { return &_mutex; } + + protected: + pthread_mutex_t _mutex; +}; + +class NonBlockingLock : public Lock { + public: + NonBlockingLock() {} + ~NonBlockingLock(){} + + int lock () { return pthread_mutex_lock (&_mutex); } + int trylock () { return pthread_mutex_trylock (&_mutex); } + int unlock() { return pthread_mutex_unlock (&_mutex); } +}; + +class LockMonitor +{ + public: + LockMonitor (Lock& lck, unsigned long l, const char *f) + : lock (lck) +#ifdef DEBUG_LOCK_MONITOR + , line (l), file (f) +#endif + { + +#ifdef DEBUG_LOCK_MONITOR + unsigned long long when; + when = get_cycles(); + cerr << when << " lock " << &lock << " at " << line << " in " << file << endl; +#endif + lock.lock (); +#ifdef DEBUG_LOCK_MONITOR + when = get_cycles(); + cerr << '\t' << when + << " locked: " + << &lock << " at " + << line << " in " << file << endl; +#endif + } + + ~LockMonitor () { + lock.unlock (); +#ifdef DEBUG_LOCK_MONITOR + unsigned long long when; + when = get_cycles(); + cerr << '\t' << when << ' ' + << " UNLOCKED " + << &lock << " at " + << line << " in " << file << endl; +#endif + } + private: + Lock& lock; +#ifdef DEBUG_LOCK_MONITOR + unsigned long line; + const char * file; +#endif +}; + +class TentativeLockMonitor +{ + public: + TentativeLockMonitor (NonBlockingLock& lck, unsigned long l, const char *f) + : lock (lck) +#ifdef DEBUG_LOCK_MONITOR + , line (l), file (f) +#endif + { + +#ifdef DEBUG_LOCK_MONITOR + unsigned long long when; + when = get_cycles(); + cerr << when << " tentative lock " << &lock << " at " << line << " in " << file << endl; +#endif + _locked = (lock.trylock() == 0); + +#ifdef DEBUG_LOCK_MONITOR + when = get_cycles(); + cerr << '\t' << when << ' ' + << _locked + << " lock: " + << &lock << " at " + << line << " in " << file << endl; +#endif + } + + ~TentativeLockMonitor () { + if (_locked) { + lock.unlock (); +#ifdef DEBUG_LOCK_MONITOR + unsigned long long when; + when = get_cycles(); + cerr << '\t' << when << ' ' + << " UNLOCKED " + << &lock << " at " + << line << " in " << file << endl; +#endif + } + } + + bool locked() { return _locked; } + + private: + NonBlockingLock& lock; + bool _locked; +#ifdef DEBUG_LOCK_MONITOR + unsigned long line; + const char * file; +#endif +}; + +class SpinLockMonitor +{ + public: + SpinLockMonitor (pthread_mutex_t *lck, unsigned long l, const char *f) + : lock (lck) +#ifdef DEBUG_LOCK_MONITOR + , line (l), file (f) +#endif + { + +#ifdef DEBUG_LOCK_MONITOR + unsigned long long when; + when = get_cycles(); + cerr << when << " spinlock " << lck << " at " << line << " in " << file << endl; +#endif + pthread_mutex_spinlock (lck); +#ifdef DEBUG_LOCK_MONITOR + when = get_cycles(); + cerr << '\t' << when + << " locked at " + << &lock << " at " + << line << " in " << file << endl; +#endif + } + + ~SpinLockMonitor () { + pthread_mutex_unlock (lock); + } + private: + pthread_mutex_t *lock; +#ifdef DEBUG_LOCK_MONITOR + unsigned long line; + const char * file; +#endif +}; + +} /* namespace */ + +#endif /* __pbd_lockmonitor_h__*/ |