forked from ddnet/ddnet
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add
CLock
wrapper for std::mutex
to replace lock_*
functions
- Loading branch information
Showing
15 changed files
with
199 additions
and
308 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
#ifndef BASE_LOCK_H | ||
#define BASE_LOCK_H | ||
|
||
#include <mutex> | ||
|
||
// Enable thread safety attributes only with clang. | ||
// The attributes can be safely erased when compiling with other compilers. | ||
#if defined(__clang__) && (!defined(SWIG)) | ||
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) | ||
#else | ||
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op | ||
#endif | ||
|
||
#define CAPABILITY(x) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) | ||
|
||
#define SCOPED_CAPABILITY \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) | ||
|
||
#define GUARDED_BY(x) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) | ||
|
||
#define PT_GUARDED_BY(x) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) | ||
|
||
#define ACQUIRED_BEFORE(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) | ||
|
||
#define ACQUIRED_AFTER(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) | ||
|
||
#define REQUIRES(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) | ||
|
||
#define REQUIRES_SHARED(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) | ||
|
||
#define ACQUIRE(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) | ||
|
||
#define ACQUIRE_SHARED(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) | ||
|
||
#define RELEASE(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) | ||
|
||
#define RELEASE_SHARED(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) | ||
|
||
#define RELEASE_GENERIC(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(release_generic_capability(__VA_ARGS__)) | ||
|
||
#define TRY_ACQUIRE(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) | ||
|
||
#define TRY_ACQUIRE_SHARED(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) | ||
|
||
#define EXCLUDES(...) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) | ||
|
||
#define ASSERT_CAPABILITY(x) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) | ||
|
||
#define ASSERT_SHARED_CAPABILITY(x) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) | ||
|
||
#define RETURN_CAPABILITY(x) \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) | ||
|
||
#define NO_THREAD_SAFETY_ANALYSIS \ | ||
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) | ||
|
||
/** | ||
* @defgroup Locks | ||
* @see Threads | ||
*/ | ||
|
||
/** | ||
* Wrapper for `std::mutex`. | ||
* | ||
* @ingroup Locks | ||
* | ||
* @remark This wrapper is only necessary because the clang thread-safety attributes | ||
* are not available for `std::mutex` except when explicitly using libc++. | ||
*/ | ||
class CAPABILITY("mutex") CLock | ||
{ | ||
public: | ||
CLock() = default; | ||
|
||
void lock() ACQUIRE() | ||
{ | ||
m_Mutex.lock(); | ||
} | ||
|
||
void unlock() RELEASE() | ||
{ | ||
m_Mutex.unlock(); | ||
} | ||
|
||
// To support negative capabilities, otherwise EXCLUDES(m_Lock) must be used instead of REQUIRES(!m_Lock) | ||
const CLock &operator!() const { return *this; } | ||
|
||
private: | ||
std::mutex m_Mutex; | ||
}; | ||
|
||
/** | ||
* RAII-style wrapper for owning a `CLock`. | ||
* | ||
* @ingroup Locks | ||
* | ||
* @remark This wrapper is only necessary because the clang thread-safety attributes | ||
* are not available for `std::lock_guard` except when explicitly using libc++. | ||
*/ | ||
class SCOPED_CAPABILITY CLockScope | ||
{ | ||
public: | ||
explicit CLockScope(CLock &Lock) ACQUIRE(Lock, m_Lock) : | ||
m_Lock(Lock) | ||
{ | ||
m_Lock.lock(); | ||
} | ||
|
||
~CLockScope() RELEASE() REQUIRES(m_Lock) | ||
{ | ||
m_Lock.unlock(); | ||
} | ||
|
||
private: | ||
CLock &m_Lock; | ||
}; | ||
|
||
#endif |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.