Enable thread safety annotations in open source version.
The thread safety annotations used by leveldb got opensourced in Abseil [1]. This CL replaces leveldb's stubs with the relevant definitions from [1], and adds annotations to the Mutex classes in the POSIX port. [1] https://github.com/abseil/abseil-cpp/blob/master/absl/base/thread_annotations.h
This commit is contained in:
parent
47cb9e2a21
commit
41172a2401
@ -202,7 +202,6 @@ EOF
|
|||||||
PLATFORM_LIBS="$PLATFORM_LIBS -lcrc32c"
|
PLATFORM_LIBS="$PLATFORM_LIBS -lcrc32c"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
# Test whether Snappy library is installed
|
# Test whether Snappy library is installed
|
||||||
# https://github.com/google/snappy
|
# https://github.com/google/snappy
|
||||||
$CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF
|
$CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF
|
||||||
@ -222,7 +221,23 @@ EOF
|
|||||||
PLATFORM_LIBS="$PLATFORM_LIBS -ltcmalloc"
|
PLATFORM_LIBS="$PLATFORM_LIBS -ltcmalloc"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f $CXXOUTPUT 2>/dev/null
|
# Test whether -Wthread-safety is available. See
|
||||||
|
# https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
|
||||||
|
# -Werror is necessary because unknown attributes only generate warnings.
|
||||||
|
$CXX $CXXFLAGS -Wthread-safety -Werror -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF
|
||||||
|
struct __attribute__((lockable)) Lock {
|
||||||
|
void Acquire() __attribute__((exclusive_lock_function()));
|
||||||
|
void Release() __attribute__((unlock_function()));
|
||||||
|
};
|
||||||
|
struct ThreadSafeType {
|
||||||
|
Lock lock_;
|
||||||
|
int data_ __attribute__((guarded_by(lock_)));
|
||||||
|
};
|
||||||
|
int main() { return 0; }
|
||||||
|
EOF
|
||||||
|
if [ "$?" = 0 ]; then
|
||||||
|
COMMON_FLAGS="$COMMON_FLAGS -Wthread-safety"
|
||||||
|
fi
|
||||||
|
|
||||||
rm -f $CXXOUTPUT 2>/dev/null
|
rm -f $CXXOUTPUT 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
#ifndef STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
|
#ifndef STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
|
||||||
#define STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
|
#define STORAGE_LEVELDB_PORT_PORT_EXAMPLE_H_
|
||||||
|
|
||||||
|
#include "port/thread_annotations.h"
|
||||||
|
|
||||||
namespace leveldb {
|
namespace leveldb {
|
||||||
namespace port {
|
namespace port {
|
||||||
|
|
||||||
@ -23,23 +25,23 @@ static const bool kLittleEndian = true /* or some other expression */;
|
|||||||
// ------------------ Threading -------------------
|
// ------------------ Threading -------------------
|
||||||
|
|
||||||
// A Mutex represents an exclusive lock.
|
// A Mutex represents an exclusive lock.
|
||||||
class Mutex {
|
class LOCKABLE Mutex {
|
||||||
public:
|
public:
|
||||||
Mutex();
|
Mutex();
|
||||||
~Mutex();
|
~Mutex();
|
||||||
|
|
||||||
// Lock the mutex. Waits until other lockers have exited.
|
// Lock the mutex. Waits until other lockers have exited.
|
||||||
// Will deadlock if the mutex is already locked by this thread.
|
// Will deadlock if the mutex is already locked by this thread.
|
||||||
void Lock();
|
void Lock() EXCLUSIVE_LOCK_FUNCTION();
|
||||||
|
|
||||||
// Unlock the mutex.
|
// Unlock the mutex.
|
||||||
// REQUIRES: This mutex was locked by this thread.
|
// REQUIRES: This mutex was locked by this thread.
|
||||||
void Unlock();
|
void Unlock() UNLOCK_FUNCTION();
|
||||||
|
|
||||||
// Optionally crash if this thread does not hold this mutex.
|
// Optionally crash if this thread does not hold this mutex.
|
||||||
// The implementation must be fast, especially if NDEBUG is
|
// The implementation must be fast, especially if NDEBUG is
|
||||||
// defined. The implementation is allowed to skip all checks.
|
// defined. The implementation is allowed to skip all checks.
|
||||||
void AssertHeld();
|
void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
|
||||||
};
|
};
|
||||||
|
|
||||||
class CondVar {
|
class CondVar {
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "port/atomic_pointer.h"
|
#include "port/atomic_pointer.h"
|
||||||
|
#include "port/thread_annotations.h"
|
||||||
|
|
||||||
#ifndef PLATFORM_IS_LITTLE_ENDIAN
|
#ifndef PLATFORM_IS_LITTLE_ENDIAN
|
||||||
#define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
|
#define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN)
|
||||||
@ -73,14 +74,14 @@ static const bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN;
|
|||||||
|
|
||||||
class CondVar;
|
class CondVar;
|
||||||
|
|
||||||
class Mutex {
|
class LOCKABLE Mutex {
|
||||||
public:
|
public:
|
||||||
Mutex();
|
Mutex();
|
||||||
~Mutex();
|
~Mutex();
|
||||||
|
|
||||||
void Lock();
|
void Lock() EXCLUSIVE_LOCK_FUNCTION();
|
||||||
void Unlock();
|
void Unlock() UNLOCK_FUNCTION();
|
||||||
void AssertHeld() { }
|
void AssertHeld() ASSERT_EXCLUSIVE_LOCK() { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CondVar;
|
friend class CondVar;
|
||||||
|
@ -5,56 +5,107 @@
|
|||||||
#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
|
#ifndef STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
|
||||||
#define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
|
#define STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
|
||||||
|
|
||||||
// Some environments provide custom macros to aid in static thread-safety
|
// Use Clang's thread safety analysis annotations when available. In other
|
||||||
// analysis. Provide empty definitions of such macros unless they are already
|
// environments, the macros receive empty definitions.
|
||||||
// defined.
|
// Usage documentation: https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
|
||||||
|
|
||||||
|
#if !defined(THREAD_ANNOTATION_ATTRIBUTE__)
|
||||||
|
|
||||||
|
#if defined(__clang__)
|
||||||
|
|
||||||
|
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
|
||||||
|
#else
|
||||||
|
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !defined(THREAD_ANNOTATION_ATTRIBUTE__)
|
||||||
|
|
||||||
|
#ifndef GUARDED_BY
|
||||||
|
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PT_GUARDED_BY
|
||||||
|
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACQUIRED_AFTER
|
||||||
|
#define ACQUIRED_AFTER(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACQUIRED_BEFORE
|
||||||
|
#define ACQUIRED_BEFORE(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef EXCLUSIVE_LOCKS_REQUIRED
|
#ifndef EXCLUSIVE_LOCKS_REQUIRED
|
||||||
#define EXCLUSIVE_LOCKS_REQUIRED(...)
|
#define EXCLUSIVE_LOCKS_REQUIRED(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SHARED_LOCKS_REQUIRED
|
#ifndef SHARED_LOCKS_REQUIRED
|
||||||
#define SHARED_LOCKS_REQUIRED(...)
|
#define SHARED_LOCKS_REQUIRED(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LOCKS_EXCLUDED
|
#ifndef LOCKS_EXCLUDED
|
||||||
#define LOCKS_EXCLUDED(...)
|
#define LOCKS_EXCLUDED(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LOCK_RETURNED
|
#ifndef LOCK_RETURNED
|
||||||
#define LOCK_RETURNED(x)
|
#define LOCK_RETURNED(x) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LOCKABLE
|
#ifndef LOCKABLE
|
||||||
#define LOCKABLE
|
#define LOCKABLE \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(lockable)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SCOPED_LOCKABLE
|
#ifndef SCOPED_LOCKABLE
|
||||||
#define SCOPED_LOCKABLE
|
#define SCOPED_LOCKABLE \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EXCLUSIVE_LOCK_FUNCTION
|
#ifndef EXCLUSIVE_LOCK_FUNCTION
|
||||||
#define EXCLUSIVE_LOCK_FUNCTION(...)
|
#define EXCLUSIVE_LOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SHARED_LOCK_FUNCTION
|
#ifndef SHARED_LOCK_FUNCTION
|
||||||
#define SHARED_LOCK_FUNCTION(...)
|
#define SHARED_LOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef EXCLUSIVE_TRYLOCK_FUNCTION
|
#ifndef EXCLUSIVE_TRYLOCK_FUNCTION
|
||||||
#define EXCLUSIVE_TRYLOCK_FUNCTION(...)
|
#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SHARED_TRYLOCK_FUNCTION
|
#ifndef SHARED_TRYLOCK_FUNCTION
|
||||||
#define SHARED_TRYLOCK_FUNCTION(...)
|
#define SHARED_TRYLOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef UNLOCK_FUNCTION
|
#ifndef UNLOCK_FUNCTION
|
||||||
#define UNLOCK_FUNCTION(...)
|
#define UNLOCK_FUNCTION(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_THREAD_SAFETY_ANALYSIS
|
#ifndef NO_THREAD_SAFETY_ANALYSIS
|
||||||
#define NO_THREAD_SAFETY_ANALYSIS
|
#define NO_THREAD_SAFETY_ANALYSIS \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASSERT_EXCLUSIVE_LOCK
|
||||||
|
#define ASSERT_EXCLUSIVE_LOCK(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ASSERT_SHARED_LOCK
|
||||||
|
#define ASSERT_SHARED_LOCK(...) \
|
||||||
|
THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
|
#endif // STORAGE_LEVELDB_PORT_THREAD_ANNOTATIONS_H_
|
||||||
|
Loading…
Reference in New Issue
Block a user