mirror of
https://github.com/llvm-mirror/libcxx.git
synced 2025-10-24 03:32:35 +08:00
As of r360984, LLD supports dependent libraries feature for ELF. libunwind, libc++abi and libc++ have library dependencies: libdl librt and libpthread, which means that when libunwind and libc++ are being statically linked (using -static-libstdc++ flag), user has to manually specify -ldl -lpthread which is onerous. This change includes the lib pragma to specify the library dependencies directly in the source that uses those libraries. This doesn't make any difference when using linkers that don't support dependent libraries. However, when using LLD that has dependent libraries feature, users no longer have to manually specifying library dependencies when using static linking, linker will pick the library automatically. Differential Revision: https://reviews.llvm.org/D62090 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@362048 91177308-0d34-0410-b5e6-96231b3b80d8
119 lines
2.9 KiB
C++
119 lines
2.9 KiB
C++
//===---------------------- 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(__unix__) && defined(__ELF__) && defined(__clang__)
|
|
#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
|