mutex revision 300770
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 182300770Sdim#ifndef _LIBCPP_HAS_NO_THREADS 183276792Sdim#include <sched.h> 184300770Sdim#endif 185227825Stheraven 186232924Stheraven#include <__undef_min_max> 187232924Stheraven 188227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 189227825Stheraven#pragma GCC system_header 190227825Stheraven#endif 191227825Stheraven 192227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 193227825Stheraven 194276792Sdim#ifndef _LIBCPP_HAS_NO_THREADS 195276792Sdim 196249989Sdimclass _LIBCPP_TYPE_VIS recursive_mutex 197227825Stheraven{ 198227825Stheraven pthread_mutex_t __m_; 199227825Stheraven 200227825Stheravenpublic: 201227825Stheraven recursive_mutex(); 202227825Stheraven ~recursive_mutex(); 203227825Stheraven 204227825Stheravenprivate: 205227825Stheraven recursive_mutex(const recursive_mutex&); // = delete; 206227825Stheraven recursive_mutex& operator=(const recursive_mutex&); // = delete; 207227825Stheraven 208227825Stheravenpublic: 209227825Stheraven void lock(); 210241900Sdim bool try_lock() _NOEXCEPT; 211241900Sdim void unlock() _NOEXCEPT; 212227825Stheraven 213227825Stheraven typedef pthread_mutex_t* native_handle_type; 214227825Stheraven _LIBCPP_INLINE_VISIBILITY 215227825Stheraven native_handle_type native_handle() {return &__m_;} 216227825Stheraven}; 217227825Stheraven 218249989Sdimclass _LIBCPP_TYPE_VIS timed_mutex 219227825Stheraven{ 220227825Stheraven mutex __m_; 221227825Stheraven condition_variable __cv_; 222227825Stheraven bool __locked_; 223227825Stheravenpublic: 224227825Stheraven timed_mutex(); 225227825Stheraven ~timed_mutex(); 226227825Stheraven 227227825Stheravenprivate: 228227825Stheraven timed_mutex(const timed_mutex&); // = delete; 229227825Stheraven timed_mutex& operator=(const timed_mutex&); // = delete; 230227825Stheraven 231227825Stheravenpublic: 232227825Stheraven void lock(); 233241900Sdim bool try_lock() _NOEXCEPT; 234227825Stheraven template <class _Rep, class _Period> 235227825Stheraven _LIBCPP_INLINE_VISIBILITY 236227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 237227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 238227825Stheraven template <class _Clock, class _Duration> 239227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 240241900Sdim void unlock() _NOEXCEPT; 241227825Stheraven}; 242227825Stheraven 243227825Stheraventemplate <class _Clock, class _Duration> 244227825Stheravenbool 245227825Stheraventimed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 246227825Stheraven{ 247227825Stheraven using namespace chrono; 248227825Stheraven unique_lock<mutex> __lk(__m_); 249227825Stheraven bool no_timeout = _Clock::now() < __t; 250227825Stheraven while (no_timeout && __locked_) 251227825Stheraven no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; 252227825Stheraven if (!__locked_) 253227825Stheraven { 254227825Stheraven __locked_ = true; 255227825Stheraven return true; 256227825Stheraven } 257227825Stheraven return false; 258227825Stheraven} 259227825Stheraven 260249989Sdimclass _LIBCPP_TYPE_VIS recursive_timed_mutex 261227825Stheraven{ 262227825Stheraven mutex __m_; 263227825Stheraven condition_variable __cv_; 264227825Stheraven size_t __count_; 265227825Stheraven pthread_t __id_; 266227825Stheravenpublic: 267227825Stheraven recursive_timed_mutex(); 268227825Stheraven ~recursive_timed_mutex(); 269227825Stheraven 270227825Stheravenprivate: 271227825Stheraven recursive_timed_mutex(const recursive_timed_mutex&); // = delete; 272227825Stheraven recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete; 273227825Stheraven 274227825Stheravenpublic: 275227825Stheraven void lock(); 276241900Sdim bool try_lock() _NOEXCEPT; 277227825Stheraven template <class _Rep, class _Period> 278227825Stheraven _LIBCPP_INLINE_VISIBILITY 279227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 280227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 281227825Stheraven template <class _Clock, class _Duration> 282227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 283241900Sdim void unlock() _NOEXCEPT; 284227825Stheraven}; 285227825Stheraven 286227825Stheraventemplate <class _Clock, class _Duration> 287227825Stheravenbool 288227825Stheravenrecursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 289227825Stheraven{ 290227825Stheraven using namespace chrono; 291227825Stheraven pthread_t __id = pthread_self(); 292227825Stheraven unique_lock<mutex> lk(__m_); 293227825Stheraven if (pthread_equal(__id, __id_)) 294227825Stheraven { 295227825Stheraven if (__count_ == numeric_limits<size_t>::max()) 296227825Stheraven return false; 297227825Stheraven ++__count_; 298227825Stheraven return true; 299227825Stheraven } 300227825Stheraven bool no_timeout = _Clock::now() < __t; 301227825Stheraven while (no_timeout && __count_ != 0) 302227825Stheraven no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout; 303227825Stheraven if (__count_ == 0) 304227825Stheraven { 305227825Stheraven __count_ = 1; 306227825Stheraven __id_ = __id; 307227825Stheraven return true; 308227825Stheraven } 309227825Stheraven return false; 310227825Stheraven} 311227825Stheraven 312227825Stheraventemplate <class _L0, class _L1> 313227825Stheravenint 314227825Stheraventry_lock(_L0& __l0, _L1& __l1) 315227825Stheraven{ 316227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 317227825Stheraven if (__u0.owns_lock()) 318227825Stheraven { 319227825Stheraven if (__l1.try_lock()) 320227825Stheraven { 321227825Stheraven __u0.release(); 322227825Stheraven return -1; 323227825Stheraven } 324227825Stheraven else 325227825Stheraven return 1; 326227825Stheraven } 327227825Stheraven return 0; 328227825Stheraven} 329227825Stheraven 330227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 331227825Stheraven 332227825Stheraventemplate <class _L0, class _L1, class _L2, class... _L3> 333227825Stheravenint 334227825Stheraventry_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) 335227825Stheraven{ 336227825Stheraven int __r = 0; 337227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 338227825Stheraven if (__u0.owns_lock()) 339227825Stheraven { 340227825Stheraven __r = try_lock(__l1, __l2, __l3...); 341227825Stheraven if (__r == -1) 342227825Stheraven __u0.release(); 343227825Stheraven else 344227825Stheraven ++__r; 345227825Stheraven } 346227825Stheraven return __r; 347227825Stheraven} 348227825Stheraven 349227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 350227825Stheraven 351227825Stheraventemplate <class _L0, class _L1> 352227825Stheravenvoid 353227825Stheravenlock(_L0& __l0, _L1& __l1) 354227825Stheraven{ 355227825Stheraven while (true) 356227825Stheraven { 357227825Stheraven { 358227825Stheraven unique_lock<_L0> __u0(__l0); 359227825Stheraven if (__l1.try_lock()) 360227825Stheraven { 361227825Stheraven __u0.release(); 362227825Stheraven break; 363227825Stheraven } 364227825Stheraven } 365227825Stheraven sched_yield(); 366227825Stheraven { 367227825Stheraven unique_lock<_L1> __u1(__l1); 368227825Stheraven if (__l0.try_lock()) 369227825Stheraven { 370227825Stheraven __u1.release(); 371227825Stheraven break; 372227825Stheraven } 373227825Stheraven } 374227825Stheraven sched_yield(); 375227825Stheraven } 376227825Stheraven} 377227825Stheraven 378227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 379227825Stheraven 380227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 381227825Stheravenvoid 382227825Stheraven__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 383227825Stheraven{ 384227825Stheraven while (true) 385227825Stheraven { 386227825Stheraven switch (__i) 387227825Stheraven { 388227825Stheraven case 0: 389227825Stheraven { 390227825Stheraven unique_lock<_L0> __u0(__l0); 391227825Stheraven __i = try_lock(__l1, __l2, __l3...); 392227825Stheraven if (__i == -1) 393227825Stheraven { 394227825Stheraven __u0.release(); 395227825Stheraven return; 396227825Stheraven } 397227825Stheraven } 398227825Stheraven ++__i; 399227825Stheraven sched_yield(); 400227825Stheraven break; 401227825Stheraven case 1: 402227825Stheraven { 403227825Stheraven unique_lock<_L1> __u1(__l1); 404227825Stheraven __i = try_lock(__l2, __l3..., __l0); 405227825Stheraven if (__i == -1) 406227825Stheraven { 407227825Stheraven __u1.release(); 408227825Stheraven return; 409227825Stheraven } 410227825Stheraven } 411227825Stheraven if (__i == sizeof...(_L3) + 1) 412227825Stheraven __i = 0; 413227825Stheraven else 414227825Stheraven __i += 2; 415227825Stheraven sched_yield(); 416227825Stheraven break; 417227825Stheraven default: 418227825Stheraven __lock_first(__i - 2, __l2, __l3..., __l0, __l1); 419227825Stheraven return; 420227825Stheraven } 421227825Stheraven } 422227825Stheraven} 423227825Stheraven 424227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 425227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 426227825Stheravenvoid 427227825Stheravenlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 428227825Stheraven{ 429227825Stheraven __lock_first(0, __l0, __l1, __l2, __l3...); 430227825Stheraven} 431227825Stheraven 432227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 433227825Stheraven 434276792Sdim#endif // !_LIBCPP_HAS_NO_THREADS 435227825Stheraven 436276792Sdimstruct _LIBCPP_TYPE_VIS_ONLY once_flag; 437276792Sdim 438227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 439227825Stheraven 440227825Stheraventemplate<class _Callable, class... _Args> 441241900Sdim_LIBCPP_INLINE_VISIBILITY 442241900Sdimvoid call_once(once_flag&, _Callable&&, _Args&&...); 443227825Stheraven 444227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 445227825Stheraven 446227825Stheraventemplate<class _Callable> 447241900Sdim_LIBCPP_INLINE_VISIBILITY 448288943Sdimvoid call_once(once_flag&, _Callable&); 449227825Stheraven 450288943Sdimtemplate<class _Callable> 451288943Sdim_LIBCPP_INLINE_VISIBILITY 452288943Sdimvoid call_once(once_flag&, const _Callable&); 453288943Sdim 454227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 455227825Stheraven 456261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY once_flag 457227825Stheraven{ 458227825Stheraven _LIBCPP_INLINE_VISIBILITY 459241900Sdim _LIBCPP_CONSTEXPR 460241900Sdim once_flag() _NOEXCEPT : __state_(0) {} 461227825Stheraven 462227825Stheravenprivate: 463227825Stheraven once_flag(const once_flag&); // = delete; 464227825Stheraven once_flag& operator=(const once_flag&); // = delete; 465227825Stheraven 466227825Stheraven unsigned long __state_; 467227825Stheraven 468227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 469227825Stheraven template<class _Callable, class... _Args> 470227825Stheraven friend 471227825Stheraven void call_once(once_flag&, _Callable&&, _Args&&...); 472227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 473227825Stheraven template<class _Callable> 474227825Stheraven friend 475288943Sdim void call_once(once_flag&, _Callable&); 476288943Sdim 477288943Sdim template<class _Callable> 478288943Sdim friend 479288943Sdim void call_once(once_flag&, const _Callable&); 480227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 481227825Stheraven}; 482227825Stheraven 483227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 484227825Stheraven 485232924Stheraventemplate <class _Fp> 486227825Stheravenclass __call_once_param 487227825Stheraven{ 488288943Sdim _Fp& __f_; 489227825Stheravenpublic: 490227825Stheraven _LIBCPP_INLINE_VISIBILITY 491288943Sdim explicit __call_once_param(_Fp& __f) : __f_(__f) {} 492227825Stheraven 493227825Stheraven _LIBCPP_INLINE_VISIBILITY 494227825Stheraven void operator()() 495227825Stheraven { 496232924Stheraven typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; 497227825Stheraven __execute(_Index()); 498227825Stheraven } 499227825Stheraven 500227825Stheravenprivate: 501227825Stheraven template <size_t ..._Indices> 502227825Stheraven _LIBCPP_INLINE_VISIBILITY 503227825Stheraven void __execute(__tuple_indices<_Indices...>) 504227825Stheraven { 505288943Sdim __invoke(_VSTD::get<0>(_VSTD::move(__f_)), _VSTD::get<_Indices>(_VSTD::move(__f_))...); 506227825Stheraven } 507227825Stheraven}; 508227825Stheraven 509227825Stheraven#else 510227825Stheraven 511232924Stheraventemplate <class _Fp> 512227825Stheravenclass __call_once_param 513227825Stheraven{ 514288943Sdim _Fp& __f_; 515227825Stheravenpublic: 516227825Stheraven _LIBCPP_INLINE_VISIBILITY 517288943Sdim explicit __call_once_param(_Fp& __f) : __f_(__f) {} 518227825Stheraven 519227825Stheraven _LIBCPP_INLINE_VISIBILITY 520227825Stheraven void operator()() 521227825Stheraven { 522227825Stheraven __f_(); 523227825Stheraven } 524227825Stheraven}; 525227825Stheraven 526227825Stheraven#endif 527227825Stheraven 528232924Stheraventemplate <class _Fp> 529227825Stheravenvoid 530227825Stheraven__call_once_proxy(void* __vp) 531227825Stheraven{ 532232924Stheraven __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); 533227825Stheraven (*__p)(); 534227825Stheraven} 535227825Stheraven 536261272Sdim_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*)); 537227825Stheraven 538227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 539227825Stheraven 540227825Stheraventemplate<class _Callable, class... _Args> 541227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 542227825Stheravenvoid 543227825Stheravencall_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) 544227825Stheraven{ 545288943Sdim if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) 546227825Stheraven { 547288943Sdim typedef tuple<_Callable&&, _Args&&...> _Gp; 548288943Sdim _Gp __f(_VSTD::forward<_Callable>(__func), _VSTD::forward<_Args>(__args)...); 549288943Sdim __call_once_param<_Gp> __p(__f); 550232924Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); 551227825Stheraven } 552227825Stheraven} 553227825Stheraven 554227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 555227825Stheraven 556227825Stheraventemplate<class _Callable> 557227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 558227825Stheravenvoid 559288943Sdimcall_once(once_flag& __flag, _Callable& __func) 560227825Stheraven{ 561288943Sdim if (__libcpp_relaxed_load(&__flag.__state_) != ~0ul) 562227825Stheraven { 563227825Stheraven __call_once_param<_Callable> __p(__func); 564227825Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); 565227825Stheraven } 566227825Stheraven} 567227825Stheraven 568288943Sdimtemplate<class _Callable> 569288943Sdiminline _LIBCPP_INLINE_VISIBILITY 570288943Sdimvoid 571288943Sdimcall_once(once_flag& __flag, const _Callable& __func) 572288943Sdim{ 573288943Sdim if (__flag.__state_ != ~0ul) 574288943Sdim { 575288943Sdim __call_once_param<const _Callable> __p(__func); 576288943Sdim __call_once(__flag.__state_, &__p, &__call_once_proxy<const _Callable>); 577288943Sdim } 578288943Sdim} 579288943Sdim 580227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 581227825Stheraven 582227825Stheraven_LIBCPP_END_NAMESPACE_STD 583227825Stheraven 584227825Stheraven#endif // _LIBCPP_MUTEX 585