diff options
Diffstat (limited to 'contrib/libc++/src/memory.cpp')
| -rw-r--r-- | contrib/libc++/src/memory.cpp | 50 | 
1 files changed, 50 insertions, 0 deletions
| diff --git a/contrib/libc++/src/memory.cpp b/contrib/libc++/src/memory.cpp index a892e75c86d0..3884a2b3abf8 100644 --- a/contrib/libc++/src/memory.cpp +++ b/contrib/libc++/src/memory.cpp @@ -7,7 +7,10 @@  //  //===----------------------------------------------------------------------===// +#define _LIBCPP_BUILDING_MEMORY  #include "memory" +#include "mutex" +#include "thread"  _LIBCPP_BEGIN_NAMESPACE_STD @@ -116,6 +119,53 @@ __shared_weak_count::__get_deleter(const type_info&) const _NOEXCEPT  #endif  // _LIBCPP_NO_RTTI +#if __has_feature(cxx_atomic) + +static const std::size_t __sp_mut_count = 16; +static mutex mut_back[__sp_mut_count]; + +_LIBCPP_CONSTEXPR __sp_mut::__sp_mut(void* p) _NOEXCEPT +   : _(p) +{ +} + +void +__sp_mut::lock() _NOEXCEPT +{ +    mutex& m = *static_cast<mutex*>(_); +    unsigned count = 0; +    while (!m.try_lock()) +    { +        if (++count > 16) +        { +            m.lock(); +            break; +        } +        this_thread::yield(); +    } +} + +void +__sp_mut::unlock() _NOEXCEPT +{ +    static_cast<mutex*>(_)->unlock(); +} + +__sp_mut& +__get_sp_mut(const void* p) +{ +    static __sp_mut muts[__sp_mut_count]  +    { +        &mut_back[ 0], &mut_back[ 1], &mut_back[ 2], &mut_back[ 3], +        &mut_back[ 4], &mut_back[ 5], &mut_back[ 6], &mut_back[ 7], +        &mut_back[ 8], &mut_back[ 9], &mut_back[10], &mut_back[11], +        &mut_back[12], &mut_back[13], &mut_back[14], &mut_back[15] +    }; +    return muts[hash<const void*>()(p) & (__sp_mut_count-1)]; +} + +#endif // __has_feature(cxx_atomic) +  void  declare_reachable(void*)  { | 
