diff options
| author | joerg <joerg@NetBSD.org> | 2013-11-11 23:42:23 +0000 |
|---|---|---|
| committer | joerg <joerg@NetBSD.org> | 2013-11-11 23:42:23 +0000 |
| commit | 7b508f5cf1cffaba9056e779bab2a09bf6767655 (patch) | |
| tree | 1ded8b22c412394ce3b7605b7da7e7d752c5b1e4 /external/bsd/libc++/dist/libcxx/src/shared_mutex.cpp | |
| parent | f4c7577e0d6de880acbb5d05bffab23df87c32d5 (diff) | |
Import libc++ r194207. This brings in various bug fixes, a good chunk of
support for the up-coming C++14 and improved compatibility with various
compilers other than Clang.
Diffstat (limited to 'external/bsd/libc++/dist/libcxx/src/shared_mutex.cpp')
| -rw-r--r-- | external/bsd/libc++/dist/libcxx/src/shared_mutex.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/external/bsd/libc++/dist/libcxx/src/shared_mutex.cpp b/external/bsd/libc++/dist/libcxx/src/shared_mutex.cpp new file mode 100644 index 00000000000..5fb22e44544 --- /dev/null +++ b/external/bsd/libc++/dist/libcxx/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<mutex> 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<mutex> lk(__mut_); + if (__state_ == 0) + { + __state_ = __write_entered_; + return true; + } + return false; +} + +void +shared_mutex::unlock() +{ + lock_guard<mutex> _(__mut_); + __state_ = 0; + __gate1_.notify_all(); +} + +// Shared ownership + +void +shared_mutex::lock_shared() +{ + unique_lock<mutex> 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<mutex> 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<mutex> _(__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 |
