diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-03-27 22:35:13 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-03-27 22:35:13 -0400 |
| commit | 107b5196f65c4e77c6c61ff830d6eb7de8b8842b (patch) | |
| tree | 1993c71221ff70dc6abacb3c360b03909fd5ca89 /lib/libcxx/src/shared_mutex.cpp | |
| parent | 33819ecfbcde6a96262c4ec5cb38e3228ead83c7 (diff) | |
| parent | a25874108470f97c5c58d72b2df49a9085c79b2e (diff) | |
| download | zig-107b5196f65c4e77c6c61ff830d6eb7de8b8842b.tar.gz zig-107b5196f65c4e77c6c61ff830d6eb7de8b8842b.zip | |
Merge pull request #4827 from ziglang/zig-cpp
support compiling and linking c++ code
Diffstat (limited to 'lib/libcxx/src/shared_mutex.cpp')
| -rw-r--r-- | lib/libcxx/src/shared_mutex.cpp | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/lib/libcxx/src/shared_mutex.cpp b/lib/libcxx/src/shared_mutex.cpp new file mode 100644 index 0000000000..5feef9f488 --- /dev/null +++ b/lib/libcxx/src/shared_mutex.cpp @@ -0,0 +1,118 @@ +//===---------------------- shared_mutex.cpp ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "__config" +#ifndef _LIBCPP_HAS_NO_THREADS + +#include "shared_mutex" +#if defined(__ELF__) && defined(_LIBCPP_LINK_PTHREAD_LIB) +#pragma comment(lib, "pthread") +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +// Shared Mutex Base +__shared_mutex_base::__shared_mutex_base() + : __state_(0) +{ +} + +// Exclusive ownership + +void +__shared_mutex_base::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_base::try_lock() +{ + unique_lock<mutex> lk(__mut_); + if (__state_ == 0) + { + __state_ = __write_entered_; + return true; + } + return false; +} + +void +__shared_mutex_base::unlock() +{ + lock_guard<mutex> _(__mut_); + __state_ = 0; + __gate1_.notify_all(); +} + +// Shared ownership + +void +__shared_mutex_base::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_base::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_base::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(); + } +} + + +// Shared Timed Mutex +// These routines are here for ABI stability +shared_timed_mutex::shared_timed_mutex() : __base() {} +void shared_timed_mutex::lock() { return __base.lock(); } +bool shared_timed_mutex::try_lock() { return __base.try_lock(); } +void shared_timed_mutex::unlock() { return __base.unlock(); } +void shared_timed_mutex::lock_shared() { return __base.lock_shared(); } +bool shared_timed_mutex::try_lock_shared() { return __base.try_lock_shared(); } +void shared_timed_mutex::unlock_shared() { return __base.unlock_shared(); } + +_LIBCPP_END_NAMESPACE_STD + +#endif // !_LIBCPP_HAS_NO_THREADS |
