Created
June 23, 2015 20:36
-
-
Save theuni/f5d6d3db9434ca546422 to your computer and use it in GitHub Desktop.
clang locking test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include <mutex> | |
#if defined(__clang__) && (!defined(SWIG)) | |
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) | |
#else | |
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op | |
#endif | |
#define EXCLUSIVE_LOCKS_REQUIRED(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__)) | |
#define LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(lockable) | |
#define SCOPED_LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) | |
#define EXCLUSIVE_LOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__)) | |
#define UNLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) | |
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) | |
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) | |
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) | |
// Defines an annotated interface for mutexes. | |
// These methods can be implemented to use any internal mutex implementation. | |
template <typename BaseMutex> | |
class LOCKABLE MutexInt { | |
public: | |
// Acquire/lock this mutex exclusively. Only one thread can have exclusive | |
// access at any one time. Write operations to guarded data require an | |
// exclusive lock. | |
void lock() EXCLUSIVE_LOCK_FUNCTION() { mutex.lock(); } | |
// Release/unlock an exclusive mutex. | |
void unlock() UNLOCK_FUNCTION() { mutex.unlock(); } | |
// Try to acquire the mutex. Returns true on success, and false on failure. | |
bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { return mutex.try_lock(); } | |
// For negative capabilities. | |
const MutexInt& operator!() const { return *this; } | |
BaseMutex mutex; | |
typedef BaseMutex type; | |
}; | |
// MutexLocker is an RAII class that acquires a mutex in its constructor, and | |
// releases it in its destructor. | |
template <typename M> | |
class SCOPED_LOCKABLE QuickLockInt { | |
private: | |
std::lock_guard<M> mylock; | |
public: | |
QuickLockInt(M &mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mylock(mu) { | |
} | |
~QuickLockInt() UNLOCK_FUNCTION() { | |
} | |
}; | |
template <typename M> | |
class SCOPED_LOCKABLE LockInt { | |
private: | |
std::unique_lock<M> mylock; | |
public: | |
typedef M type; | |
LockInt(M &mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mylock(mu) {} | |
void lock() EXCLUSIVE_LOCK_FUNCTION() { mylock.lock(); } | |
void unlock() UNLOCK_FUNCTION() { mylock.unlock(); } | |
bool try_lock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { return mylock.try_lock(); } | |
bool owns_lock() const { return mylock.owns_lock(); } | |
~LockInt() UNLOCK_FUNCTION() { | |
} | |
}; | |
typedef MutexInt<std::mutex> Mutex; | |
typedef MutexInt<std::recursive_mutex> RecursiveMutex; | |
typedef LockInt<Mutex> UniqueLock; | |
typedef QuickLockInt<Mutex> QuickUniqueLock; | |
typedef LockInt<RecursiveMutex> RecursiveLock; | |
typedef QuickLockInt<RecursiveMutex> QuickRecursiveLock; | |
#define LOCK(x) RecursiveLock lock(x) | |
#define ULOCK(x) UniqueLock lock(x) | |
#define QUICKLOCK(x) QuickRecursiveLock lock(x) | |
#define QUICKULOCK(x) QuickUniqueLock lock(x) | |
#define ENTER_CRITICAL_SECTION(cs) \ | |
{ \ | |
(cs).lock(); \ | |
} | |
#define LEAVE_CRITICAL_SECTION(cs) \ | |
{ \ | |
(cs).unlock(); \ | |
} | |
static RecursiveMutex cs_main; | |
static int myint = 0; | |
static std::vector<int*> GUARDED_BY(cs_main) vec(1,&myint); | |
int* func2() | |
{ | |
LOCK(cs_main); | |
return vec[0]; | |
} | |
void func1() EXCLUSIVE_LOCKS_REQUIRED(cs_main) | |
{ | |
func2(); | |
vec.clear(); | |
} | |
int main() | |
{ | |
int* unguarded = func2(); | |
*unguarded = 3; | |
LOCK(cs_main); | |
func1(); | |
unguarded = func2(); | |
return *unguarded; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment