Commit 799a718f authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Pure C++ for TSAN annotation wrappers

Summary:
[Folly] Pure C++ for TSAN annotation wrappers, v.s. using the preprocessor.

The implementation uses the preprocessor in order to support platforms without weak symbols, but the interface is now pure C++.

Reviewed By: nbronson

Differential Revision: D10291176

fbshipit-source-id: 3636652793b8d0da59c7c9b1095d4c1b0c506372
parent 07515573
......@@ -174,9 +174,8 @@
#endif
#endif
/* These functions are defined by the TSAN runtime library and allow us to
* annotate mutexes appopriately for TSAN. */
#ifdef FOLLY_SANITIZE_THREAD
// These functions are defined by the TSAN runtime library and enable
// annotating mutexes for TSAN.
extern "C" FOLLY_ATTR_WEAK void
AnnotateRWLockCreate(const char* f, int l, const volatile void* addr);
extern "C" FOLLY_ATTR_WEAK void
......@@ -193,61 +192,3 @@ extern "C" FOLLY_ATTR_WEAK void AnnotateBenignRaceSized(
const volatile void* addr,
long size,
const char* desc);
#define FOLLY_ANNOTATE_RWLOCK_CREATE(addr) \
AnnotateRWLockCreate(__FILE__, __LINE__, (addr))
#define FOLLY_ANNOTATE_RWLOCK_CREATE_STATIC(addr) \
AnnotateRWLockCreateStatic(__FILE__, __LINE__, (addr))
#define FOLLY_ANNOTATE_RWLOCK_DESTROY(addr) \
AnnotateRWLockDestroy(__FILE__, __LINE__, (addr))
#define FOLLY_ANNOTATE_RWLOCK_ACQUIRED(addr, w) \
AnnotateRWLockAcquired(__FILE__, __LINE__, (addr), (w))
#define FOLLY_ANNOTATE_RWLOCK_TRY_ACQUIRED(result, addr, w) \
if ((result)) { \
FOLLY_ANNOTATE_RWLOCK_ACQUIRED((addr), (w)); \
}
#define FOLLY_ANNOTATE_RWLOCK_RELEASED(addr, w) \
AnnotateRWLockReleased(__FILE__, __LINE__, (addr), (w))
#define FOLLY_ANNOTATE_BENIGN_RACE_SIZED(addr, size, desc) \
AnnotateBenignRaceSized(__FILE__, __LINE__, (addr), (size), (desc))
#else
#define FOLLY_ANNOTATE_RWLOCK_CREATE(addr) \
(void)addr; \
do { \
} while (0)
#define FOLLY_ANNOTATE_RWLOCK_CREATE_STATIC(addr) \
(void)addr; \
do { \
} while (0)
#define FOLLY_ANNOTATE_RWLOCK_DESTROY(addr) \
(void)addr; \
do { \
} while (0)
#define FOLLY_ANNOTATE_RWLOCK_ACQUIRED(addr, w) \
(void)addr; \
(void)w; \
do { \
} while (0)
#define FOLLY_ANNOTATE_RWLOCK_TRY_ACQUIRED(result, addr, w) \
(void)result; \
(void)addr; \
(void)w; \
do { \
} while (0)
#define FOLLY_ANNOTATE_RWLOCK_RELEASED(addr, w) \
(void)addr; \
(void)w; \
do { \
} while (0)
#define FOLLY_ANNOTATE_BENIGN_RACE_SIZED(addr, size, desc) \
(void)addr; \
(void)size; \
(void)desc; \
do { \
} while (0)
#endif
#define FOLLY_ANNOTATE_RWLOCK_RDLOCK 0L
#define FOLLY_ANNOTATE_RWLOCK_WRLOCK 1L
This diff is collapsed.
......@@ -20,6 +20,7 @@
#include <folly/experimental/observer/detail/Core.h>
#include <folly/experimental/observer/detail/GraphCycleDetector.h>
#include <folly/futures/Future.h>
#include <folly/synchronization/SanitizeThread.h>
namespace folly {
namespace observer_detail {
......@@ -84,16 +85,22 @@ class ObserverManager {
// work will be the one that unlocks it. To avoid noise with TSAN,
// annotate that the thread has released the mutex, and then annotate
// the async thread as acquiring the mutex.
FOLLY_ANNOTATE_RWLOCK_RELEASED(
&instance->versionMutex_, FOLLY_ANNOTATE_RWLOCK_RDLOCK);
annotate_rwlock_released(
&instance->versionMutex_,
annotate_rwlock_level::rdlock,
__FILE__,
__LINE__);
instance->scheduleCurrent([core = std::move(core),
instancePtr = instance.get(),
rh = std::move(rh),
force]() {
// Make TSAN know that the current thread owns the read lock now.
FOLLY_ANNOTATE_RWLOCK_ACQUIRED(
&instancePtr->versionMutex_, FOLLY_ANNOTATE_RWLOCK_RDLOCK);
annotate_rwlock_acquired(
&instancePtr->versionMutex_,
annotate_rwlock_level::rdlock,
__FILE__,
__LINE__);
core->refresh(instancePtr->version_, force);
});
......
/*
* Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <folly/CPortability.h>
#include <folly/Portability.h>
namespace folly {
enum class annotate_rwlock_level : long {
rdlock = 0,
wrlock = 1,
};
namespace detail {
FOLLY_ALWAYS_INLINE static void annotate_ignore(...) {}
} // namespace detail
#if _MSC_VER
#define FOLLY_DETAIL_ANNOTATE(name, ...) detail::annotate_ignore(__VA_ARGS__)
#else
#define FOLLY_DETAIL_ANNOTATE(name, ...) Annotate##name(__VA_ARGS__)
#endif
FOLLY_ALWAYS_INLINE static void annotate_rwlock_create(
void const volatile* const addr,
char const* const f,
int const l) {
if (kIsSanitizeThread) {
FOLLY_DETAIL_ANNOTATE(RWLockCreate, f, l, addr);
}
}
FOLLY_ALWAYS_INLINE static void annotate_rwlock_create_static(
void const volatile* const addr,
char const* const f,
int const l) {
if (kIsSanitizeThread) {
FOLLY_DETAIL_ANNOTATE(RWLockCreateStatic, f, l, addr);
}
}
FOLLY_ALWAYS_INLINE static void annotate_rwlock_destroy(
void const volatile* const addr,
char const* const f,
int const l) {
if (kIsSanitizeThread) {
FOLLY_DETAIL_ANNOTATE(RWLockDestroy, f, l, addr);
}
}
FOLLY_ALWAYS_INLINE static void annotate_rwlock_acquired(
void const volatile* const addr,
annotate_rwlock_level const w,
char const* const f,
int const l) {
if (kIsSanitizeThread) {
FOLLY_DETAIL_ANNOTATE(RWLockAcquired, f, l, addr, static_cast<long>(w));
}
}
FOLLY_ALWAYS_INLINE static void annotate_rwlock_try_acquired(
void const volatile* const addr,
annotate_rwlock_level const w,
bool const result,
char const* const f,
int const l) {
if (result) {
annotate_rwlock_acquired(addr, w, f, l);
}
}
FOLLY_ALWAYS_INLINE static void annotate_rwlock_released(
void const volatile* const addr,
annotate_rwlock_level const w,
char const* const f,
int const l) {
if (kIsSanitizeThread) {
FOLLY_DETAIL_ANNOTATE(RWLockReleased, f, l, addr, static_cast<long>(w));
}
}
FOLLY_ALWAYS_INLINE static void annotate_benign_race_sized(
void const volatile* const addr,
long const size,
char const* const desc,
char const* const f,
int const l) {
if (kIsSanitizeThread) {
FOLLY_DETAIL_ANNOTATE(BenignRaceSized, f, l, addr, size, desc);
}
}
#undef FOLLY_DETAIL_ANNOTATE
} // namespace folly
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