This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Fix thread annotations on shared_mutex and shared_timed_mutex
ClosedPublic

Authored by ldionne on Jul 3 2023, 8:05 AM.

Details

Summary

Based on the comment in https://reviews.llvm.org/D54290#4418958, these
attributes need to be on the top-level functions in order to work
properly. Also, add tests.

Fixes http://llvm.org/PR57035.

Diff Detail

Event Timeline

ldionne created this revision.Jul 3 2023, 8:05 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 3 2023, 8:06 AM
ldionne requested review of this revision.Jul 3 2023, 8:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 3 2023, 8:06 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik added a subscriber: philnik.Jul 3 2023, 8:39 AM

Could we add some sort of tests for this?

Thanks for picking this up!

Could we add some sort of tests for this?

There are several existing tests, see libcxx/test/libcxx/thread/thread.mutex/thread_safety_*. What should work:

std::shared_mutex m;
int data __attribute__((guarded_by(m)));
void read(int);

++foo; // warning, but probably no need to test this: libc++ has
       // nothing to do with it, it's due to the attribute above.
m.lock();
++foo; // ok.
m.unlock();

if (m.try_lock())
  ++foo; // ok.
m.unlock();

m.lock_shared();
read(foo); // ok.
++foo; // warning.
m.unlock_shared();
libcxx/include/shared_mutex
187

You could also replace the underscore by a space, or go with just "mutex". This string is used as a "capability kind" in diagnostics.

229

Otherwise, if you keep the type, it probably makes sense to write shared_timed_mutex here.

235–236

Should also have _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_capability(true)): it's a try-acquire, the time parameter is irrelevant for thread safety.

235–236

Same here.

249–250

Same for these two, of course _LIBCPP_THREAD_SAFETY_ANNOTATION(try_acquire_shared_capability(true)).

Side note: you can include in the commit message that this fixes #57035.

philnik requested changes to this revision.Jul 3 2023, 3:44 PM

Thanks for picking this up!

Could we add some sort of tests for this?

There are several existing tests, see libcxx/test/libcxx/thread/thread.mutex/thread_safety_*. What should work:

std::shared_mutex m;
int data __attribute__((guarded_by(m)));
void read(int);

++foo; // warning, but probably no need to test this: libc++ has
       // nothing to do with it, it's due to the attribute above.
m.lock();
++foo; // ok.
m.unlock();

if (m.try_lock())
  ++foo; // ok.
m.unlock();

m.lock_shared();
read(foo); // ok.
++foo; // warning.
m.unlock_shared();

Then I definitely want some tests for this.

libcxx/include/shared_mutex
197–206

As a fly-by we might as well _Uglify the attributes.

This revision now requires changes to proceed.Jul 3 2023, 3:44 PM
if (m.try_lock())
  ++foo; // ok.
m.unlock();

That would generate a warning, better:

if (m.try_lock()) {
  ++foo; // ok.
  m.unlock();
}

And there is no point in testing for that warning, because we're doing this in Clang. We should essentially only test that we got the right attribute.

ldionne marked 6 inline comments as done.Jul 4 2023, 10:51 AM

Thanks for the comments!

ldionne updated this revision to Diff 537131.Jul 4 2023, 10:52 AM
ldionne edited the summary of this revision. (Show Details)

Address comments.

ldionne updated this revision to Diff 537132.Jul 4 2023, 10:53 AM

Improve test synopsis.

aaronpuchert accepted this revision.Jul 4 2023, 3:46 PM

Annotations and tests look good to me. Guess the tests require C++14/17, respectively, and need to guarded accordingly.

ldionne updated this revision to Diff 537314.Jul 5 2023, 5:36 AM

Update UNSUPPORTED markup for added tests

philnik accepted this revision.Jul 5 2023, 8:21 AM

LGTM with green CI.

This revision is now accepted and ready to land.Jul 5 2023, 8:21 AM
ldionne updated this revision to Diff 537495.Jul 5 2023, 2:12 PM

Add markup to the tests