mutex revision 288943
1227825Stheraven// -*- C++ -*- 2227825Stheraven//===--------------------------- mutex ------------------------------------===// 3227825Stheraven// 4227825Stheraven// The LLVM Compiler Infrastructure 5227825Stheraven// 6227825Stheraven// This file is dual licensed under the MIT and the University of Illinois Open 7227825Stheraven// Source Licenses. See LICENSE.TXT for details. 8227825Stheraven// 9227825Stheraven//===----------------------------------------------------------------------===// 10227825Stheraven 11227825Stheraven#ifndef _LIBCPP_MUTEX 12227825Stheraven#define _LIBCPP_MUTEX 13227825Stheraven 14227825Stheraven/* 15227825Stheraven mutex synopsis 16227825Stheraven 17227825Stheravennamespace std 18227825Stheraven{ 19227825Stheraven 20227825Stheravenclass mutex 21227825Stheraven{ 22227825Stheravenpublic: 23241900Sdim constexpr mutex() noexcept; 24227825Stheraven ~mutex(); 25227825Stheraven 26227825Stheraven mutex(const mutex&) = delete; 27227825Stheraven mutex& operator=(const mutex&) = delete; 28227825Stheraven 29227825Stheraven void lock(); 30227825Stheraven bool try_lock(); 31227825Stheraven void unlock(); 32227825Stheraven 33227825Stheraven typedef pthread_mutex_t* native_handle_type; 34227825Stheraven native_handle_type native_handle(); 35227825Stheraven}; 36227825Stheraven 37227825Stheravenclass recursive_mutex 38227825Stheraven{ 39227825Stheravenpublic: 40227825Stheraven recursive_mutex(); 41227825Stheraven ~recursive_mutex(); 42227825Stheraven 43227825Stheraven recursive_mutex(const recursive_mutex&) = delete; 44227825Stheraven recursive_mutex& operator=(const recursive_mutex&) = delete; 45227825Stheraven 46227825Stheraven void lock(); 47241900Sdim bool try_lock() noexcept; 48227825Stheraven void unlock(); 49227825Stheraven 50227825Stheraven typedef pthread_mutex_t* native_handle_type; 51227825Stheraven native_handle_type native_handle(); 52227825Stheraven}; 53227825Stheraven 54227825Stheravenclass timed_mutex 55227825Stheraven{ 56227825Stheravenpublic: 57227825Stheraven timed_mutex(); 58227825Stheraven ~timed_mutex(); 59227825Stheraven 60227825Stheraven timed_mutex(const timed_mutex&) = delete; 61227825Stheraven timed_mutex& operator=(const timed_mutex&) = delete; 62227825Stheraven 63227825Stheraven void lock(); 64227825Stheraven bool try_lock(); 65227825Stheraven template <class Rep, class Period> 66227825Stheraven bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 67227825Stheraven template <class Clock, class Duration> 68227825Stheraven bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 69227825Stheraven void unlock(); 70227825Stheraven}; 71227825Stheraven 72227825Stheravenclass recursive_timed_mutex 73227825Stheraven{ 74227825Stheravenpublic: 75227825Stheraven recursive_timed_mutex(); 76227825Stheraven ~recursive_timed_mutex(); 77227825Stheraven 78227825Stheraven recursive_timed_mutex(const recursive_timed_mutex&) = delete; 79227825Stheraven recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete; 80227825Stheraven 81227825Stheraven void lock(); 82241900Sdim bool try_lock() noexcept; 83227825Stheraven template <class Rep, class Period> 84227825Stheraven bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 85227825Stheraven template <class Clock, class Duration> 86227825Stheraven bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 87227825Stheraven void unlock(); 88227825Stheraven}; 89227825Stheraven 90227825Stheravenstruct defer_lock_t {}; 91227825Stheravenstruct try_to_lock_t {}; 92227825Stheravenstruct adopt_lock_t {}; 93227825Stheraven 94227825Stheravenconstexpr defer_lock_t defer_lock{}; 95227825Stheravenconstexpr try_to_lock_t try_to_lock{}; 96227825Stheravenconstexpr adopt_lock_t adopt_lock{}; 97227825Stheraven 98227825Stheraventemplate <class Mutex> 99227825Stheravenclass lock_guard 100227825Stheraven{ 101227825Stheravenpublic: 102227825Stheraven typedef Mutex mutex_type; 103227825Stheraven 104227825Stheraven explicit lock_guard(mutex_type& m); 105227825Stheraven lock_guard(mutex_type& m, adopt_lock_t); 106227825Stheraven ~lock_guard(); 107227825Stheraven 108227825Stheraven lock_guard(lock_guard const&) = delete; 109227825Stheraven lock_guard& operator=(lock_guard const&) = delete; 110227825Stheraven}; 111227825Stheraven 112227825Stheraventemplate <class Mutex> 113227825Stheravenclass unique_lock 114227825Stheraven{ 115227825Stheravenpublic: 116227825Stheraven typedef Mutex mutex_type; 117241900Sdim unique_lock() noexcept; 118227825Stheraven explicit unique_lock(mutex_type& m); 119241900Sdim unique_lock(mutex_type& m, defer_lock_t) noexcept; 120227825Stheraven unique_lock(mutex_type& m, try_to_lock_t); 121227825Stheraven unique_lock(mutex_type& m, adopt_lock_t); 122227825Stheraven template <class Clock, class Duration> 123227825Stheraven unique_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); 124227825Stheraven template <class Rep, class Period> 125227825Stheraven unique_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); 126227825Stheraven ~unique_lock(); 127227825Stheraven 128227825Stheraven unique_lock(unique_lock const&) = delete; 129227825Stheraven unique_lock& operator=(unique_lock const&) = delete; 130227825Stheraven 131241900Sdim unique_lock(unique_lock&& u) noexcept; 132241900Sdim unique_lock& operator=(unique_lock&& u) noexcept; 133227825Stheraven 134227825Stheraven void lock(); 135227825Stheraven bool try_lock(); 136227825Stheraven 137227825Stheraven template <class Rep, class Period> 138227825Stheraven bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); 139227825Stheraven template <class Clock, class Duration> 140227825Stheraven bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); 141227825Stheraven 142227825Stheraven void unlock(); 143227825Stheraven 144241900Sdim void swap(unique_lock& u) noexcept; 145241900Sdim mutex_type* release() noexcept; 146227825Stheraven 147241900Sdim bool owns_lock() const noexcept; 148241900Sdim explicit operator bool () const noexcept; 149241900Sdim mutex_type* mutex() const noexcept; 150227825Stheraven}; 151227825Stheraven 152227825Stheraventemplate <class Mutex> 153241900Sdim void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y) noexcept; 154227825Stheraven 155227825Stheraventemplate <class L1, class L2, class... L3> 156227825Stheraven int try_lock(L1&, L2&, L3&...); 157227825Stheraventemplate <class L1, class L2, class... L3> 158227825Stheraven void lock(L1&, L2&, L3&...); 159227825Stheraven 160227825Stheravenstruct once_flag 161227825Stheraven{ 162241900Sdim constexpr once_flag() noexcept; 163227825Stheraven 164227825Stheraven once_flag(const once_flag&) = delete; 165227825Stheraven once_flag& operator=(const once_flag&) = delete; 166227825Stheraven}; 167227825Stheraven 168227825Stheraventemplate<class Callable, class ...Args> 169227825Stheraven void call_once(once_flag& flag, Callable&& func, Args&&... args); 170227825Stheraven 171227825Stheraven} // std 172227825Stheraven 173227825Stheraven*/ 174227825Stheraven 175227825Stheraven#include <__config> 176227825Stheraven#include <__mutex_base> 177227825Stheraven#include <functional> 178288943Sdim#include <memory> 179227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 180227825Stheraven#include <tuple> 181227825Stheraven#endif 182276792Sdim#include <sched.h> 183227825Stheraven 184232924Stheraven#include <__undef_min_max> 185232924Stheraven 186227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 187227825Stheraven#pragma GCC system_header 188227825Stheraven#endif 189227825Stheraven 190227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 191227825Stheraven 192276792Sdim#ifndef _LIBCPP_HAS_NO_THREADS 193276792Sdim 194249989Sdimclass _LIBCPP_TYPE_VIS recursive_mutex 195227825Stheraven{ 196227825Stheraven pthread_mutex_t __m_; 197227825Stheraven 198227825Stheravenpublic: 199227825Stheraven recursive_mutex(); 200227825Stheraven ~recursive_mutex(); 201227825Stheraven 202227825Stheravenprivate: 203227825Stheraven recursive_mutex(const recursive_mutex&); // = delete; 204227825Stheraven recursive_mutex& operator=(const recursive_mutex&); // = delete; 205227825Stheraven 206227825Stheravenpublic: 207227825Stheraven void lock(); 208241900Sdim bool try_lock() _NOEXCEPT; 209241900Sdim void unlock() _NOEXCEPT; 210227825Stheraven 211227825Stheraven typedef pthread_mutex_t* native_handle_type; 212227825Stheraven _LIBCPP_INLINE_VISIBILITY 213227825Stheraven native_handle_type native_handle() {return &__m_;} 214227825Stheraven}; 215227825Stheraven 216249989Sdimclass _LIBCPP_TYPE_VIS timed_mutex 217227825Stheraven{ 218227825Stheraven mutex __m_; 219227825Stheraven condition_variable __cv_; 220227825Stheraven bool __locked_; 221227825Stheravenpublic: 222227825Stheraven timed_mutex(); 223227825Stheraven ~timed_mutex(); 224227825Stheraven 225227825Stheravenprivate: 226227825Stheraven timed_mutex(const timed_mutex&); // = delete; 227227825Stheraven timed_mutex& operator=(const timed_mutex&); // = delete; 228227825Stheraven 229227825Stheravenpublic: 230227825Stheraven void lock(); 231241900Sdim bool try_lock() _NOEXCEPT; 232227825Stheraven template <class _Rep, class _Period> 233227825Stheraven _LIBCPP_INLINE_VISIBILITY 234227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 235227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 236227825Stheraven template <class _Clock, class _Duration> 237227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 238241900Sdim void unlock() _NOEXCEPT; 239227825Stheraven}; 240227825Stheraven 241227825Stheraventemplate <class _Clock, class _Duration> 242227825Stheravenbool 243227825Stheraventimed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 244227825Stheraven{ 245227825Stheraven using namespace chrono; 246227825Stheraven unique_lock<mutex> __lk(__m_); 247227825Stheraven bool no_timeout = _Clock::now() < __t; 248227825Stheraven while (no_timeout && __locked_) 249227825Stheraven no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; 250227825Stheraven if (!__locked_) 251227825Stheraven { 252227825Stheraven __locked_ = true; 253227825Stheraven return true; 254227825Stheraven } 255227825Stheraven return false; 256227825Stheraven} 257227825Stheraven 258249989Sdimclass _LIBCPP_TYPE_VIS recursive_timed_mutex 259227825Stheraven{ 260227825Stheraven mutex __m_; 261227825Stheraven condition_variable __cv_; 262227825Stheraven size_t __count_; 263227825Stheraven pthread_t __id_; 264227825Stheravenpublic: 265227825Stheraven recursive_timed_mutex(); 266227825Stheraven ~recursive_timed_mutex(); 267227825Stheraven 268227825Stheravenprivate: 269227825Stheraven recursive_timed_mutex(const recursive_timed_mutex&); // = delete; 270227825Stheraven recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete; 271227825Stheraven 272227825Stheravenpublic: 273227825Stheraven void lock(); 274241900Sdim bool try_lock() _NOEXCEPT; 275227825Stheraven template <class _Rep, class _Period> 276227825Stheraven _LIBCPP_INLINE_VISIBILITY 277227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 278227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 279227825Stheraven template <class _Clock, class _Duration> 280227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 281241900Sdim void unlock() _NOEXCEPT; 282227825Stheraven}; 283227825Stheraven 284227825Stheraventemplate <class _Clock, class _Duration> 285227825Stheravenbool 286227825Stheravenrecursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 287227825Stheraven{ 288227825Stheraven using namespace chrono; 289227825Stheraven pthread_t __id = pthread_self(); 290227825Stheraven unique_lock<mutex> lk(__m_); 291227825Stheraven if (pthread_equal(__id, __id_)) 292227825Stheraven { 293227825Stheraven if (__count_ == numeric_limits<size_t>::max()) 294227825Stheraven return false; 295227825Stheraven ++__count_; 296227825Stheraven return true; 297227825Stheraven } 298227825Stheraven bool no_timeout = _Clock::now() < __t; 299227825Stheraven while (no_timeout && __count_ != 0) 300227825Stheraven no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout; 301227825Stheraven if (__count_ == 0) 302227825Stheraven { 303227825Stheraven __count_ = 1; 304227825Stheraven __id_ = __id; 305227825Stheraven return true; 306227825Stheraven } 307227825Stheraven return false; 308227825Stheraven} 309227825Stheraven 310227825Stheraventemplate <class _L0, class _L1> 311227825Stheravenint 312227825Stheraventry_lock(_L0& __l0, _L1& __l1) 313227825Stheraven{ 314227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 315227825Stheraven if (__u0.owns_lock()) 316227825Stheraven { 317227825Stheraven if (__l1.try_lock()) 318227825Stheraven { 319227825Stheraven __u0.release(); 320227825Stheraven return -1; 321227825Stheraven } 322227825Stheraven else 323227825Stheraven return 1; 324227825Stheraven } 325227825Stheraven return 0; 326227825Stheraven} 327227825Stheraven 328227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 329227825Stheraven 330227825Stheraventemplate <class _L0, class _L1, class _L2, class... _L3> 331227825Stheravenint 332227825Stheraventry_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) 333227825Stheraven{ 334227825Stheraven int __r = 0; 335227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 336227825Stheraven if (__u0.owns_lock()) 337227825Stheraven { 338227825Stheraven __r = try_lock(__l1, __l2, __l3...); 339227825Stheraven if (__r == -1) 340227825Stheraven __u0.release(); 341227825Stheraven else 342227825Stheraven ++__r; 343227825Stheraven } 344227825Stheraven return __r; 345227825Stheraven} 346227825Stheraven 347227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 348227825Stheraven 349227825Stheraventemplate <class _L0, class _L1> 350227825Stheravenvoid 351227825Stheravenlock(_L0& __l0, _L1& __l1) 352227825Stheraven{ 353227825Stheraven while (true) 354227825Stheraven { 355227825Stheraven { 356227825Stheraven unique_lock<_L0> __u0(__l0); 357227825Stheraven if (__l1.try_lock()) 358227825Stheraven { 359227825Stheraven __u0.release(); 360227825Stheraven break; 361227825Stheraven } 362227825Stheraven } 363227825Stheraven sched_yield(); 364227825Stheraven { 365227825Stheraven unique_lock<_L1> __u1(__l1); 366227825Stheraven if (__l0.try_lock()) 367227825Stheraven { 368227825Stheraven __u1.release(); 369227825Stheraven break; 370227825Stheraven } 371227825Stheraven } 372227825Stheraven sched_yield(); 373227825Stheraven } 374227825Stheraven} 375227825Stheraven 376227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 377227825Stheraven 378227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 379227825Stheravenvoid 380227825Stheraven__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 381227825Stheraven{ 382227825Stheraven while (true) 383227825Stheraven { 384227825Stheraven switch (__i) 385227825Stheraven { 386227825Stheraven case 0: 387227825Stheraven { 388227825Stheraven unique_lock<_L0> __u0(__l0); 389227825Stheraven __i = try_lock(__l1, __l2, __l3...); 390227825Stheraven if (__i == -1) 391227825Stheraven { 392227825Stheraven __u0.release(); 393227825Stheraven return; 394227825Stheraven } 395227825Stheraven } 396227825Stheraven ++__i; 397227825Stheraven sched_yield(); 398227825Stheraven break; 399227825Stheraven case 1: 400227825Stheraven { 401227825Stheraven unique_lock<_L1> __u1(__l1); 402227825Stheraven __i = try_lock(__l2, __l3..., __l0); 403227825Stheraven if (__i == -1) 404227825Stheraven { 405227825Stheraven __u1.release(); 406227825Stheraven return; 407227825Stheraven } 408227825Stheraven } 409227825Stheraven if (__i == sizeof...(_L3) + 1) 410227825Stheraven __i = 0; 411227825Stheraven else 412227825Stheraven __i += 2; 413227825Stheraven sched_yield(); 414227825Stheraven break; 415227825Stheraven default: 416227825Stheraven __lock_first(__i - 2, __l2, __l3..., __l0, __l1); 417227825Stheraven return; 418227825Stheraven } 419227825Stheraven } 420227825Stheraven} 421227825Stheraven 422227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 423227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 424227825Stheravenvoid 425227825Stheravenlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 426227825Stheraven{ 427227825Stheraven __lock_first(0, __l0, __l1, __l2, __l3...); 428227825Stheraven} 429227825Stheraven 430227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 431227825Stheraven 432276792Sdim#endif // !_LIBCPP_HAS_NO_THREADS 433227825Stheraven 434276792Sdimstruct _LIBCPP_TYPE_VIS_ONLY once_flag; 435276792Sdim 436227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 437227825Stheraven 438227825Stheraventemplate<class _Callable, class... _Args> 439241900Sdim_LIBCPP_INLINE_VISIBILITY 440241900Sdimvoid call_once(once_flag&, _Callable&&, _Args&&...); 441227825Stheraven 442227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 443227825Stheraven 444227825Stheraventemplate<class _Callable> 445241900Sdim_LIBCPP_INLINE_VISIBILITY 446288943Sdimvoid call_once(once_flag&, _Callable&); 447227825Stheraven 448288943Sdimtemplate<class _Callable> 449288943Sdim_LIBCPP_INLINE_VISIBILITY 450288943Sdimvoid call_once(once_flag&, const _Callable&); 451288943Sdim 452227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 453227825Stheraven 454261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY once_flag 455227825Stheraven{ 456227825Stheraven _LIBCPP_INLINE_VISIBILITY 457241900Sdim _LIBCPP_CONSTEXPR 458241900Sdim once_flag() _NOEXCEPT : __state_(0) {} 459227825Stheraven 460227825Stheravenprivate: 461227825Stheraven once_flag(const once_flag&); // = delete; 462227825Stheraven once_flag& operator=(const once_flag&); // = delete; 463227825Stheraven 464227825Stheraven unsigned long __state_; 465227825Stheraven 466227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 467227825Stheraven template<class _Callable, class... _Args> 468227825Stheraven friend 469227825Stheraven void call_once(once_flag&, _Callable&&, _Args&&...); 470227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 471227825Stheraven template<class _Callable> 472227825Stheraven friend 473288943Sdim void call_once(once_flag&, _Callable&); 474288943Sdim 475288943Sdim template<class _Callable> 476288943Sdim friend 477288943Sdim void call_once(once_flag&, const _Callable&); 478227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 479227825Stheraven}; 480227825Stheraven 481227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 482227825Stheraven 483232924Stheraventemplate <class _Fp> 484227825Stheravenclass __call_once_param 485227825Stheraven{ 486288943Sdim _Fp& __f_; 487227825Stheravenpublic: 488227825Stheraven _LIBCPP_INLINE_VISIBILITY 489288943Sdim explicit __call_once_param(_Fp& __f) : __f_(__f) {} 490227825Stheraven 491227825Stheraven _LIBCPP_INLINE_VISIBILITY 492227825Stheraven void operator()() 493227825Stheraven { 494232924Stheraven typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; 495227825Stheraven __execute(_Index()); 496227825Stheraven } 497227825Stheraven 498227825Stheravenprivate: 499227825Stheraven template <size_t ..._Indices> 500227825Stheraven _LIBCPP_INLINE_VISIBILITY 501227825Stheraven void __execute(__tuple_indices<_Indices...>) 502227825Stheraven { 503288943Sdim __invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...); 504227825Stheraven } 505227825Stheraven}; 506227825Stheraven 507227825Stheraven#else 508227825Stheraven 509232924Stheraventemplate <class _Fp> 510227825Stheravenclass __call_once_param 511227825Stheraven{ 512288943Sdim _Fp& __f_; 513227825Stheravenpublic: 514227825Stheraven _LIBCPP_INLINE_VISIBILITY 515288943Sdim explicit __call_once_param(_Fp& __f) : __f_(__f) {} 516227825Stheraven 517227825Stheraven _LIBCPP_INLINE_VISIBILITY 518227825Stheraven void operator()() 519227825Stheraven { 520227825Stheraven __f_(); 521227825Stheraven } 522227825Stheraven}; 523227825Stheraven 524227825Stheraven#endif 525227825Stheraven 526232924Stheraventemplate <class _Fp> 527227825Stheravenvoid 528227825Stheraven__call_once_proxy(void* __vp) 529227825Stheraven{ 530232924Stheraven __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); 531227825Stheraven (*__p)(); 532227825Stheraven} 533227825Stheraven 534261272Sdim_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*)); 535227825Stheraven 536227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 537227825Stheraven 538227825Stheraventemplate<class _Callable, class... _Args> 539227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 540227825Stheravenvoid 541227825Stheravencall_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) 542227825Stheraven{ 543288943Sdim if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) 544227825Stheraven { 545288943Sdim typedef tuple<_Callable&&, _Args&&...> _Gp; 546288943Sdim _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); 547288943Sdim __call_once_param<_Gp> __p(__f); 548232924Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); 549227825Stheraven } 550227825Stheraven} 551227825Stheraven 552227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 553227825Stheraven 554227825Stheraventemplate<class _Callable> 555227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 556227825Stheravenvoid 557288943Sdimcall_once(once_flag& __flag, _Callable& __func) 558227825Stheraven{ 559288943Sdim if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) 560227825Stheraven { 561227825Stheraven __call_once_param<_Callable> __p(__func); 562227825Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); 563227825Stheraven } 564227825Stheraven} 565227825Stheraven 566288943Sdimtemplate<class _Callable> 567288943Sdiminline _LIBCPP_INLINE_VISIBILITY 568288943Sdimvoid 569288943Sdimcall_once(once_flag& __flag, const _Callable& __func) 570288943Sdim{ 571288943Sdim if (__flag.__state_ != ~0ul) 572288943Sdim { 573288943Sdim __call_once_param<const _Callable> __p(__func); 574288943Sdim __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>); 575288943Sdim } 576288943Sdim} 577288943Sdim 578227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 579227825Stheraven 580227825Stheraven_LIBCPP_END_NAMESPACE_STD 581227825Stheraven 582227825Stheraven#endif // _LIBCPP_MUTEX 583