From 22ca1336dcfb663d86a6892dbe1e48eee20bb6db Mon Sep 17 00:00:00 2001 From: dim Date: Wed, 5 Mar 2014 19:30:36 +0000 Subject: MFC r261283: Import libc++ 3.4 release. This contains a lot of bugfixes, and some preliminary support for C++1y. MFC r261604: HEAD is not buildable for the past day. Commit a 'quick fix' in order to permit buildworld to complete. Reviewed by: theraven MFC r261608: Apply a cleaner solution for the sign warnings that can occur when compiling libc++'s header with -Wsystem-headers on. This has also been submitted upstream. Reported by: asomers MFC r261801: An ABI incompatibility crept into the libc++ 3.4 import in r261283. It was caused by upstream libc++ commit r194536, which aimed to make the headers more standards-compliant, by making std::pair's copy constructor trivial. Unfortunately, this could cause certain C++ applications using shared libraries built against the previous version of libc++ to crash. Fix the ABI incompatibility by making std::pair's copy constructor non-trivial again. Please note: Any C++ applications or shared libraries built with libc++ between r261283 and this revision should be recompiled. Reported by: stefanf --- contrib/libc++/src/shared_mutex.cpp | 101 ++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 contrib/libc++/src/shared_mutex.cpp (limited to 'contrib/libc++/src/shared_mutex.cpp') diff --git a/contrib/libc++/src/shared_mutex.cpp b/contrib/libc++/src/shared_mutex.cpp new file mode 100644 index 0000000..5fb22e4 --- /dev/null +++ b/contrib/libc++/src/shared_mutex.cpp @@ -0,0 +1,101 @@ +//===---------------------- shared_mutex.cpp ------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#define _LIBCPP_BUILDING_SHARED_MUTEX +#include "shared_mutex" + +_LIBCPP_BEGIN_NAMESPACE_STD + +shared_mutex::shared_mutex() + : __state_(0) +{ +} + +// Exclusive ownership + +void +shared_mutex::lock() +{ + unique_lock lk(__mut_); + while (__state_ & __write_entered_) + __gate1_.wait(lk); + __state_ |= __write_entered_; + while (__state_ & __n_readers_) + __gate2_.wait(lk); +} + +bool +shared_mutex::try_lock() +{ + unique_lock lk(__mut_); + if (__state_ == 0) + { + __state_ = __write_entered_; + return true; + } + return false; +} + +void +shared_mutex::unlock() +{ + lock_guard _(__mut_); + __state_ = 0; + __gate1_.notify_all(); +} + +// Shared ownership + +void +shared_mutex::lock_shared() +{ + unique_lock lk(__mut_); + while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_) + __gate1_.wait(lk); + unsigned num_readers = (__state_ & __n_readers_) + 1; + __state_ &= ~__n_readers_; + __state_ |= num_readers; +} + +bool +shared_mutex::try_lock_shared() +{ + unique_lock lk(__mut_); + unsigned num_readers = __state_ & __n_readers_; + if (!(__state_ & __write_entered_) && num_readers != __n_readers_) + { + ++num_readers; + __state_ &= ~__n_readers_; + __state_ |= num_readers; + return true; + } + return false; +} + +void +shared_mutex::unlock_shared() +{ + lock_guard _(__mut_); + unsigned num_readers = (__state_ & __n_readers_) - 1; + __state_ &= ~__n_readers_; + __state_ |= num_readers; + if (__state_ & __write_entered_) + { + if (num_readers == 0) + __gate2_.notify_one(); + } + else + { + if (num_readers == __n_readers_ - 1) + __gate1_.notify_one(); + } +} + + +_LIBCPP_END_NAMESPACE_STD -- cgit v1.1