diff options
author | dim <dim@FreeBSD.org> | 2014-01-30 07:44:22 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2014-01-30 07:44:22 +0000 |
commit | 0b319638e352dd16f2e5a243bd3826d37eef1680 (patch) | |
tree | add3759d4df7ee10d814c3b2561c3c28fcd9cef2 /contrib/libc++/src/shared_mutex.cpp | |
parent | 9cecf9778c1472e916ad20086c11e4bf332ba6ad (diff) | |
parent | c3e10da3dc0f616b78ccf85206fdcf4c92f8ac85 (diff) | |
download | FreeBSD-src-0b319638e352dd16f2e5a243bd3826d37eef1680.zip FreeBSD-src-0b319638e352dd16f2e5a243bd3826d37eef1680.tar.gz |
Import libc++ 3.4 release. This contains a lot of bugfixes, and some
preliminary support for C++1y.
MFC after: 3 weeks
Diffstat (limited to 'contrib/libc++/src/shared_mutex.cpp')
-rw-r--r-- | contrib/libc++/src/shared_mutex.cpp | 101 |
1 files changed, 101 insertions, 0 deletions
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<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 |