Last active
May 26, 2018 02:39
-
-
Save bstaletic/9084c975107db6c5d1b5e7396514ca11 to your computer and use it in GitHub Desktop.
Clang thread annotations - STL test
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
// Compile with clang++ -c -Wthread-safety | |
#include "Mutex.h" | |
class BankAccount { | |
private: | |
std::mutex mu; | |
int balance GUARDED_BY(mu); | |
void withdrawImpl(int amount) REQUIRES(mu) { | |
balance -= amount; // OK. Caller must have locked mu. | |
test(amount); | |
} | |
void test(int a) REQUIRES(mu) { | |
balance *= a; | |
} | |
public: | |
void withdraw(int amount) { | |
// Change UniqueLock to LockGuard to use a std::lock_guard< std::mutex> wrapper | |
mu.lock(); | |
withdrawImpl(amount); // OK. We've locked mu. | |
} // WARNING! Failed to unlock mu. - Not triggered with UniqueLock or LockGuard | |
}; |
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
#ifndef YCM_MUTEX_H | |
#define YCM_MUTEX_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 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) | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment