Use absl::Mutex instead of custom implementation (#1356)

Makes `common::Mutex` an alias for `absl::Mutex` and replaces the logic inside `common::MutexLocker` with `absl::MutexLock`.

A future PR can then remove these classes entirely and replace references to it across the Cartographer code base with the Abseil classes directly.
master
Arno Fleck 2018-08-03 11:15:50 +02:00 committed by Wally B. Feed
parent b841ebf170
commit 12e11856af
4 changed files with 31 additions and 61 deletions

View File

@ -95,7 +95,9 @@ cc_library(
deps = [ deps = [
":cc_protos", ":cc_protos",
"@boost//:iostreams", "@boost//:iostreams",
"@com_google_absl//absl/base",
"@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:optional",
"@com_google_absl//absl/synchronization",
"@com_google_glog//:glog", "@com_google_glog//:glog",
"@org_cairographics_cairo//:cairo", "@org_cairographics_cairo//:cairo",
"@org_ceres_solver_ceres_solver//:ceres", "@org_ceres_solver_ceres_solver//:ceres",

View File

@ -17,83 +17,50 @@
#ifndef CARTOGRAPHER_COMMON_MUTEX_H_ #ifndef CARTOGRAPHER_COMMON_MUTEX_H_
#define CARTOGRAPHER_COMMON_MUTEX_H_ #define CARTOGRAPHER_COMMON_MUTEX_H_
#include <condition_variable> #include "absl/base/thread_annotations.h"
#include <mutex> #include "absl/synchronization/mutex.h"
#include "cartographer/common/time.h" #include "cartographer/common/time.h"
namespace cartographer { namespace cartographer {
namespace common { namespace common {
// Enable thread safety attributes only with clang.
// The attributes can be safely erased when compiling with other compilers.
#if defined(__SUPPORT_TS_ANNOTATION__) || defined(__clang__)
#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
#else
#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
#endif
#define CAPABILITY(x) THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
#define SCOPED_CAPABILITY THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
#define REQUIRES(...) \ #define REQUIRES(...) \
THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
#define ACQUIRE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
#define RELEASE(...) \
THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
#define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) #define EXCLUDES(...) THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
#define NO_THREAD_SAFETY_ANALYSIS \ // TODO(CodeArno): Replace references in code to absl::Mutex directly.
THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) using Mutex = absl::Mutex;
// Defines an annotated mutex that can only be locked through its scoped locker // A RAII class that acquires a mutex in its constructor, and
// implementation. // releases it in its destructor. It also implements waiting functionality on
class CAPABILITY("mutex") Mutex { // conditions that get checked whenever the mutex is released.
// TODO(CodeArno): Replace MutexLocker instantiations in the codebase with
// absl::MutexLock.
class SCOPED_LOCKABLE MutexLocker {
public: public:
// A RAII class that acquires a mutex in its constructor, and MutexLocker(Mutex* mutex) EXCLUSIVE_LOCK_FUNCTION(mutex)
// releases it in its destructor. It also implements waiting functionality on : mutex_(mutex), lock_(mutex) {}
// conditions that get checked whenever the mutex is released.
class SCOPED_CAPABILITY Locker {
public:
Locker(Mutex* mutex) ACQUIRE(mutex) : mutex_(mutex), lock_(mutex->mutex_) {}
~Locker() RELEASE() { ~MutexLocker() UNLOCK_FUNCTION() {}
mutex_->condition_.notify_all();
lock_.unlock();
}
template <typename Predicate> template <typename Predicate>
void Await(Predicate predicate) REQUIRES(this) { void Await(Predicate predicate) REQUIRES(this) {
mutex_->condition_.wait(lock_, predicate); mutex_->Await(absl::Condition(&predicate));
} }
template <typename Predicate> template <typename Predicate>
bool AwaitWithTimeout(Predicate predicate, common::Duration timeout) bool AwaitWithTimeout(Predicate predicate, common::Duration timeout)
REQUIRES(this) { REQUIRES(this) {
return mutex_->condition_.wait_for(lock_, timeout, predicate); return mutex_->AwaitWithTimeout(absl::Condition(&predicate),
} absl::FromChrono(timeout));
}
private:
Mutex* mutex_;
std::unique_lock<std::mutex> lock_;
};
private: private:
std::condition_variable condition_; absl::Mutex* mutex_;
std::mutex mutex_; absl::MutexLock lock_;
}; };
using MutexLocker = Mutex::Locker;
} // namespace common } // namespace common
} // namespace cartographer } // namespace cartographer

View File

@ -28,7 +28,7 @@ namespace {
class Receiver { class Receiver {
public: public:
void Receive(int number) { void Receive(int number) {
Mutex::Locker locker(&mutex_); MutexLocker locker(&mutex_);
received_numbers_.push_back(number); received_numbers_.push_back(number);
} }

View File

@ -27,6 +27,8 @@ if(NOT TARGET standalone_absl)
set(ABSEIL_LIBRARY_PATH set(ABSEIL_LIBRARY_PATH
"${ABSEIL_PROJECT_BUILD_DIR}/absl/synchronization/${prefix}absl_synchronization${suffix}") "${ABSEIL_PROJECT_BUILD_DIR}/absl/synchronization/${prefix}absl_synchronization${suffix}")
set(ABSEIL_DEPENDENT_LIBRARIES set(ABSEIL_DEPENDENT_LIBRARIES
"${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_symbolize${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/time/${prefix}absl_time${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/algorithm/${prefix}absl_algorithm${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/algorithm/${prefix}absl_algorithm${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/base/${prefix}absl_base${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/base/${prefix}absl_base${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/base/${prefix}absl_dynamic_annotations${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/base/${prefix}absl_dynamic_annotations${suffix}"
@ -41,13 +43,12 @@ if(NOT TARGET standalone_absl)
"${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_leak_check${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_leak_check${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_stack_consumption${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_stack_consumption${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_stacktrace${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_stacktrace${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/debugging/${prefix}absl_symbolize${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/memory/${prefix}absl_memory${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/memory/${prefix}absl_memory${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/meta/${prefix}absl_meta${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/meta/${prefix}absl_meta${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/numeric/${prefix}absl_int128${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/numeric/${prefix}absl_int128${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/numeric/${prefix}absl_numeric${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/numeric/${prefix}absl_numeric${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/strings/${prefix}absl_strings${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/strings/${prefix}absl_strings${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/time/${prefix}absl_time${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/synchronization/${prefix}absl_synchronization${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/types/${prefix}absl_any${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/types/${prefix}absl_any${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/types/${prefix}absl_bad_any_cast${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/types/${prefix}absl_bad_any_cast${suffix}"
"${ABSEIL_PROJECT_BUILD_DIR}/absl/types/${prefix}absl_bad_optional_access${suffix}" "${ABSEIL_PROJECT_BUILD_DIR}/absl/types/${prefix}absl_bad_optional_access${suffix}"