<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div class="moz-cite-prefix">On 10/31/2021 3:36 PM, Aaron Puchert
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:7dd43b40-0544-64c3-b861-38cfc8dcd754@alice-dsl.net">Thanks
for letting me know. (I barely follow the list.)
<br>
<blockquote type="cite">
<blockquote type="cite">On Sat, Oct 30, 2021 at 9:28 PM Randell
Jesup via cfe-dev <a class="moz-txt-link-rfc2396E" href="mailto:cfe-dev@lists.llvm.org"><cfe-dev@lists.llvm.org></a> wrote:
<br>
<blockquote type="cite">One way to possibly handle the
reader/writer vs readers case (where reads on the writing
thread don't need to lock) would be to be able to say
"guarded by this or that", in this case something like
GUARDED_BY(mMutex, MainThread) (GUARDED_BY(mMutex ||
MainThread) ??).
<br>
</blockquote>
</blockquote>
</blockquote>
<br>
There has been some work on logical expressions in capability
attributes in
<a class="moz-txt-link-freetext" href="https://reviews.llvm.org/rG7c192b452fa2b3c63ed547e0ff88a5e62765b59f">https://reviews.llvm.org/rG7c192b452fa2b3c63ed547e0ff88a5e62765b59f</a>,
but I believe it's not functional yet. I thought about the
semantics of this a bit, but don't have a good understanding yet.
<br>
<br>
If you want accesses to a resource to be protected, it's in
general not sufficient to have one of a set of capabilities. There
can only be one. What happens in this scenario is that there is a
certain period of time where the resource is exclusive to the main
thread, and another where it's only accessible via mutex (even if
the main thread were to access it). So maybe logical expressions
aren't the right way to understand this situation, but rather
there should be different types, one that has
GUARDED_BY(MainThread) and another that has GUARDED_BY(mMutex),
and at some point we convert between them. In some sense the
protection regime changes throughout the lifetime, and for static
analysis that means we need a new (static) type.
<br>
</blockquote>
<p><br>
</p>
<p>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).<br>
</p>
<p>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).<br>
</p>
<p><br>
</p>
<p>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().</p>
<p>We also have an RAII MutexAutoTryLock class, which is like
MutexAutoLock but does a trylock operation, and also you can
convert it to bool to see if it obtained the lock. I don't think
this is easily representable in the current system. (I'll note
that we use it 4 times in our codebase, and 3 of those are in
Mutext test code, so I don't care that much ;-) .)<br>
</p>
<p><br>
</p>
<p>Randell Jesup, Mozilla<br>
</p>
</body>
</html>