[cfe-dev] Who is working on/has worked on Capability analysis (-Wthread-safety)?
Randell Jesup via cfe-dev
cfe-dev at lists.llvm.org
Thu Nov 4 21:32:43 PDT 2021
On 11/4/2021 6:55 PM, Aaron Puchert wrote:
> Am 04.11.21 um 04:40 schrieb Randell Jesup:
>>
>>
>> Well, the example I gave doesn't match that, I believe. This is a
>> value only written on Thread 1, and read on Thread 1 and on other
>> threads. The requirements for locking would be the lock around all
>> writes (on thread 1), and lock around all reads from threads *other*
>> than thread 1. Reads from Thread 1 don't need to lock, since they're
>> on the only thread that ever writes to the value. This is
>> conceptually GUARDED_BY(mMutex || OnThread1).
>>
>> The case you're referencing sounds more like "value is freely written
>> and read on thread 1, then at some point later access to it is
>> provided to other threads, and after that happens access is
>> controlled by a mutex" - where the protection regime changes over
>> time (and may also correlate with specific methods, like an Init()
>> method).
>>
> You're absolutely right, I was misreading your case.
>
> What you're describing sounds in fact like thread 1 always has a
> shared lock, which it sometimes promotes to exclusive lock, then
> demotes to a shared lock again. The other threads can only acquire
> shared locks, because thread 1 doesn't ever release its shared lock.
> Now there are multiple ways to write that down:
>
You're correct, that's a reasonable way to model this pattern using
locks for everything. The pattern I mentioned is data-race safe (it
shouldn't trigger tsan alerts), but doesn't allow for validation of
safety. It depends on the developers following the rules for that variable.
>> We have another pattern that's interesting, where a method may use
>> Maybe<MutexAutoLock> lock(std::in_place, mMutex); (Maybe<> is
>> effectively std::optional). This allows us to lock.reset() instead
>> of using MutexAutoUnlock lock(mLock), which will lead to an extra
>> lock/unlock pair compared to Maybe<> and lock.reset().
>>
> Supporting that would be hard, because we'd need to look into the
> Maybe type, and then the analysis isn't local anymore. However, the
> analysis supports “premature unlocking” of scopes, i.e. you can write
> lock.Unlock(). I've even added support for “relockable scopes”, where
> you can lock.Lock() again. (Have a look at the MutexLocker in
> https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#mutex-h to see
> what is possible.)
>
I've checked, and the reason for this pattern is basically as I
mentioned; to allow for unlocking of an RAII lock without an added
lock/unlock pair on exit of the scope. If we can do "MutexAutoLock
lock(mMutex); ...; if (foo) { lock.Unlock();
MethodThatWeCantHoldLockIn(); return; } ..." then we don't need the
Maybe<> stuff.
I presume support for an RAII unlocker isn't likely soon.
Thanks again, this has been very helpful.
Randell Jesup, Mozilla
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20211105/c6ed0e30/attachment.html>
More information about the cfe-dev
mailing list