Commit 85465c8e authored by Dan Melnic's avatar Dan Melnic Committed by Facebook Github Bot

Add PicoSpinLock TSAN annotations

Summary: Add PicoSpinLock TSAN annotations

Reviewed By: yfeldblum

Differential Revision: D16653917

fbshipit-source-id: d388a31824f1278fe79ab4a42e21a66781b879df
parent 113e159c
......@@ -49,6 +49,7 @@
#include <folly/Portability.h>
#include <folly/synchronization/AtomicUtil.h>
#include <folly/synchronization/SanitizeThread.h>
#include <folly/synchronization/detail/Sleeper.h>
namespace folly {
......@@ -131,11 +132,10 @@ struct PicoSpinLock {
* got it.
*/
bool try_lock() const {
auto previous = atomic_fetch_set(
*reinterpret_cast<std::atomic<UIntType>*>(&lock_),
Bit,
std::memory_order_acquire);
return !previous;
auto ret = try_lock_internal();
annotate_rwlock_try_acquired(
this, annotate_rwlock_level::wrlock, ret, __FILE__, __LINE__);
return ret;
}
/*
......@@ -143,9 +143,11 @@ struct PicoSpinLock {
*/
void lock() const {
detail::Sleeper sleeper;
while (!try_lock()) {
while (!try_lock_internal()) {
sleeper.wait();
}
annotate_rwlock_acquired(
this, annotate_rwlock_level::wrlock, __FILE__, __LINE__);
}
/*
......@@ -153,12 +155,24 @@ struct PicoSpinLock {
* integer.
*/
void unlock() const {
annotate_rwlock_released(
this, annotate_rwlock_level::wrlock, __FILE__, __LINE__);
auto previous = atomic_fetch_reset(
*reinterpret_cast<std::atomic<UIntType>*>(&lock_),
Bit,
std::memory_order_release);
DCHECK(previous);
}
private:
// called by lock/try_lock - this is not TSAN aware
bool try_lock_internal() const {
auto previous = atomic_fetch_set(
*reinterpret_cast<std::atomic<UIntType>*>(&lock_),
Bit,
std::memory_order_acquire);
return !previous;
}
};
} // namespace folly
......@@ -189,6 +189,29 @@ TEST(SmallLocks, PicoSpinSigned) {
}
EXPECT_EQ(val.getData(), -8);
}
TEST(SmallLocks, PicoSpinLockThreadSanitizer) {
SKIP_IF(!folly::kIsSanitizeThread) << "Enabled in TSAN mode only";
typedef PicoSpinLock<int16_t, 0> Lock;
{
Lock a;
Lock b;
a.init(-8);
b.init(-8);
{
std::lock_guard<Lock> ga(a);
std::lock_guard<Lock> gb(b);
}
{
std::lock_guard<Lock> gb(b);
EXPECT_DEATH(
[&]() { std::lock_guard<Lock> ga(a); }(),
"Cycle in lock order graph");
}
}
}
#endif
TEST(SmallLocks, RegClobber) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment