[PATCH] D87066: Thread safety analysis: Improve documentation for scoped capabilities
Aaron Puchert via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 3 15:43:58 PDT 2020
aaronpuchert updated this revision to Diff 289826.
aaronpuchert marked an inline comment as done.
aaronpuchert added a comment.
- More detailed description how scoped capabilities work.
- Make the comment wording more consistent with existing comments and the previous explanation.
- Properly implement the destructor in the presence of an `Unlock()` function: we need to keep track of the status then.
- Add try-acquire functions on scoped lock.
- Fix compiler errors.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D87066/new/
https://reviews.llvm.org/D87066
Files:
clang/docs/ThreadSafetyAnalysis.rst
Index: clang/docs/ThreadSafetyAnalysis.rst
===================================================================
--- clang/docs/ThreadSafetyAnalysis.rst
+++ clang/docs/ThreadSafetyAnalysis.rst
@@ -402,6 +402,13 @@
and destructor refer to the capability via different names; see the
``MutexLocker`` class in :ref:`mutexheader`, below.
+Scoped capabilities are treated as capabilities that are implicitly acquired
+on construction and released on destruction. They are associated with
+the set of (regular) capabilities named in thread safety attributes on the
+constructor. Acquire-type attributes on other member functions are treated as
+applying to that set of associated capabilities, while ``RELEASE`` implies that
+a function releases all associated capabilities in whatever mode they're held.
+
TRY_ACQUIRE(<bool>, ...), TRY_ACQUIRE_SHARED(<bool>, ...)
---------------------------------------------------------
@@ -886,19 +893,78 @@
const Mutex& operator!() const { return *this; }
};
+ // Tag types for selecting a constructor.
+ struct adopt_lock_t {} inline constexpr adopt_lock = {};
+ struct defer_lock_t {} inline constexpr defer_lock = {};
+ struct shared_lock_t {} inline constexpr shared_lock = {};
// MutexLocker is an RAII class that acquires a mutex in its constructor, and
// releases it in its destructor.
class SCOPED_CAPABILITY MutexLocker {
private:
Mutex* mut;
+ bool locked;
public:
- MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) {
+ // Acquire mu, implicitly acquire *this and associate it with mu.
+ MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu), locked(true) {
mu->Lock();
}
+
+ // Assume mu is held, implicitly acquire *this and associate it with mu.
+ MutexLocker(Mutex *mu, adopt_lock_t) REQUIRES(mu) : mut(mu), locked(true) {}
+
+ // Acquire mu in shared mode, implicitly acquire *this and connect to mu.
+ MutexLocker(Mutex *mu, shared_lock_t) ACQUIRE_SHARED(mu) : mut(mu), locked(true) {
+ mu->ReaderLock();
+ }
+
+ // Assume mu is held in shared mode, implicitly acquire *this and associate it with mu.
+ MutexLocker(Mutex *mu, adopt_lock_t, shared_lock_t) REQUIRES_SHARED(mu)
+ : mut(mu), locked(true) {}
+
+ // Assume mu is not held, implicitly acquire *this and associate it with mu.
+ MutexLocker(Mutex *mu, defer_lock_t) EXCLUDES(mu) : mut(mu), locked(false) {}
+
+ // Release *this and all associated mutexes, if they are still held.
+ // There is no warning if the scope was already unlocked before.
~MutexLocker() RELEASE() {
+ if (locked)
+ mut->GenericUnlock();
+ }
+
+ // Acquire all associated mutexes exclusively.
+ void Lock() ACQUIRE() {
+ mut->Lock();
+ locked = true;
+ }
+
+ // Try to acquire all associated mutexes exclusively.
+ bool TryLock() TRY_ACQUIRE(true) {
+ return locked = mut->TryLock();
+ }
+
+ // Acquire all associated mutexes in shared mode.
+ void ReaderLock() ACQUIRE_SHARED() {
+ mut->ReaderLock();
+ locked = true;
+ }
+
+ // Try to acquire all associated mutexes in shared mode.
+ bool ReaderTryLock() TRY_ACQUIRE_SHARED(true) {
+ return locked = mut->ReaderTryLock();
+ }
+
+ // Release all associated mutexes. Warn on double unlock.
+ void Unlock() RELEASE() {
mut->Unlock();
+ locked = false;
+ }
+
+ // Release all associated mutexes. Warn on double unlock.
+ void ReaderUnlock() RELEASE() {
+ mut->ReaderUnlock();
+ locked = false;
}
};
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D87066.289826.patch
Type: text/x-patch
Size: 3559 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200903/047924f7/attachment.bin>
More information about the cfe-commits
mailing list