mutex revision 232924
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: 23227825Stheraven mutex(); 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(); 47227825Stheraven bool try_lock(); 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(); 82227825Stheraven bool try_lock(); 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; 117227825Stheraven unique_lock(); 118227825Stheraven explicit unique_lock(mutex_type& m); 119227825Stheraven unique_lock(mutex_type& m, defer_lock_t); 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 131227825Stheraven unique_lock(unique_lock&& u); 132227825Stheraven unique_lock& operator=(unique_lock&& u); 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 144227825Stheraven void swap(unique_lock& u); 145227825Stheraven mutex_type* release(); 146227825Stheraven 147227825Stheraven bool owns_lock() const; 148227825Stheraven explicit operator bool () const; 149227825Stheraven mutex_type* mutex() const; 150227825Stheraven}; 151227825Stheraven 152227825Stheraventemplate <class Mutex> 153227825Stheraven void swap(unique_lock<Mutex>& x, unique_lock<Mutex>& y); 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{ 162227825Stheraven constexpr once_flag(); 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> 178227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 179227825Stheraven#include <tuple> 180227825Stheraven#endif 181227825Stheraven 182232924Stheraven#include <__undef_min_max> 183232924Stheraven 184227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 185227825Stheraven#pragma GCC system_header 186227825Stheraven#endif 187227825Stheraven 188227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 189227825Stheraven 190227825Stheravenclass _LIBCPP_VISIBLE recursive_mutex 191227825Stheraven{ 192227825Stheraven pthread_mutex_t __m_; 193227825Stheraven 194227825Stheravenpublic: 195227825Stheraven recursive_mutex(); 196227825Stheraven ~recursive_mutex(); 197227825Stheraven 198227825Stheravenprivate: 199227825Stheraven recursive_mutex(const recursive_mutex&); // = delete; 200227825Stheraven recursive_mutex& operator=(const recursive_mutex&); // = delete; 201227825Stheraven 202227825Stheravenpublic: 203227825Stheraven void lock(); 204227825Stheraven bool try_lock(); 205227825Stheraven void unlock(); 206227825Stheraven 207227825Stheraven typedef pthread_mutex_t* native_handle_type; 208227825Stheraven _LIBCPP_INLINE_VISIBILITY 209227825Stheraven native_handle_type native_handle() {return &__m_;} 210227825Stheraven}; 211227825Stheraven 212227825Stheravenclass _LIBCPP_VISIBLE timed_mutex 213227825Stheraven{ 214227825Stheraven mutex __m_; 215227825Stheraven condition_variable __cv_; 216227825Stheraven bool __locked_; 217227825Stheravenpublic: 218227825Stheraven timed_mutex(); 219227825Stheraven ~timed_mutex(); 220227825Stheraven 221227825Stheravenprivate: 222227825Stheraven timed_mutex(const timed_mutex&); // = delete; 223227825Stheraven timed_mutex& operator=(const timed_mutex&); // = delete; 224227825Stheraven 225227825Stheravenpublic: 226227825Stheraven void lock(); 227227825Stheraven bool try_lock(); 228227825Stheraven template <class _Rep, class _Period> 229227825Stheraven _LIBCPP_INLINE_VISIBILITY 230227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 231227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 232227825Stheraven template <class _Clock, class _Duration> 233227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 234227825Stheraven void unlock(); 235227825Stheraven}; 236227825Stheraven 237227825Stheraventemplate <class _Clock, class _Duration> 238227825Stheravenbool 239227825Stheraventimed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 240227825Stheraven{ 241227825Stheraven using namespace chrono; 242227825Stheraven unique_lock<mutex> __lk(__m_); 243227825Stheraven bool no_timeout = _Clock::now() < __t; 244227825Stheraven while (no_timeout && __locked_) 245227825Stheraven no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; 246227825Stheraven if (!__locked_) 247227825Stheraven { 248227825Stheraven __locked_ = true; 249227825Stheraven return true; 250227825Stheraven } 251227825Stheraven return false; 252227825Stheraven} 253227825Stheraven 254227825Stheravenclass _LIBCPP_VISIBLE recursive_timed_mutex 255227825Stheraven{ 256227825Stheraven mutex __m_; 257227825Stheraven condition_variable __cv_; 258227825Stheraven size_t __count_; 259227825Stheraven pthread_t __id_; 260227825Stheravenpublic: 261227825Stheraven recursive_timed_mutex(); 262227825Stheraven ~recursive_timed_mutex(); 263227825Stheraven 264227825Stheravenprivate: 265227825Stheraven recursive_timed_mutex(const recursive_timed_mutex&); // = delete; 266227825Stheraven recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete; 267227825Stheraven 268227825Stheravenpublic: 269227825Stheraven void lock(); 270227825Stheraven bool try_lock(); 271227825Stheraven template <class _Rep, class _Period> 272227825Stheraven _LIBCPP_INLINE_VISIBILITY 273227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 274227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 275227825Stheraven template <class _Clock, class _Duration> 276227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 277227825Stheraven void unlock(); 278227825Stheraven}; 279227825Stheraven 280227825Stheraventemplate <class _Clock, class _Duration> 281227825Stheravenbool 282227825Stheravenrecursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 283227825Stheraven{ 284227825Stheraven using namespace chrono; 285227825Stheraven pthread_t __id = pthread_self(); 286227825Stheraven unique_lock<mutex> lk(__m_); 287227825Stheraven if (pthread_equal(__id, __id_)) 288227825Stheraven { 289227825Stheraven if (__count_ == numeric_limits<size_t>::max()) 290227825Stheraven return false; 291227825Stheraven ++__count_; 292227825Stheraven return true; 293227825Stheraven } 294227825Stheraven bool no_timeout = _Clock::now() < __t; 295227825Stheraven while (no_timeout && __count_ != 0) 296227825Stheraven no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout; 297227825Stheraven if (__count_ == 0) 298227825Stheraven { 299227825Stheraven __count_ = 1; 300227825Stheraven __id_ = __id; 301227825Stheraven return true; 302227825Stheraven } 303227825Stheraven return false; 304227825Stheraven} 305227825Stheraven 306227825Stheraventemplate <class _L0, class _L1> 307227825Stheravenint 308227825Stheraventry_lock(_L0& __l0, _L1& __l1) 309227825Stheraven{ 310227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 311227825Stheraven if (__u0.owns_lock()) 312227825Stheraven { 313227825Stheraven if (__l1.try_lock()) 314227825Stheraven { 315227825Stheraven __u0.release(); 316227825Stheraven return -1; 317227825Stheraven } 318227825Stheraven else 319227825Stheraven return 1; 320227825Stheraven } 321227825Stheraven return 0; 322227825Stheraven} 323227825Stheraven 324227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 325227825Stheraven 326227825Stheraventemplate <class _L0, class _L1, class _L2, class... _L3> 327227825Stheravenint 328227825Stheraventry_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) 329227825Stheraven{ 330227825Stheraven int __r = 0; 331227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 332227825Stheraven if (__u0.owns_lock()) 333227825Stheraven { 334227825Stheraven __r = try_lock(__l1, __l2, __l3...); 335227825Stheraven if (__r == -1) 336227825Stheraven __u0.release(); 337227825Stheraven else 338227825Stheraven ++__r; 339227825Stheraven } 340227825Stheraven return __r; 341227825Stheraven} 342227825Stheraven 343227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 344227825Stheraven 345227825Stheraventemplate <class _L0, class _L1> 346227825Stheravenvoid 347227825Stheravenlock(_L0& __l0, _L1& __l1) 348227825Stheraven{ 349227825Stheraven while (true) 350227825Stheraven { 351227825Stheraven { 352227825Stheraven unique_lock<_L0> __u0(__l0); 353227825Stheraven if (__l1.try_lock()) 354227825Stheraven { 355227825Stheraven __u0.release(); 356227825Stheraven break; 357227825Stheraven } 358227825Stheraven } 359227825Stheraven sched_yield(); 360227825Stheraven { 361227825Stheraven unique_lock<_L1> __u1(__l1); 362227825Stheraven if (__l0.try_lock()) 363227825Stheraven { 364227825Stheraven __u1.release(); 365227825Stheraven break; 366227825Stheraven } 367227825Stheraven } 368227825Stheraven sched_yield(); 369227825Stheraven } 370227825Stheraven} 371227825Stheraven 372227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 373227825Stheraven 374227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 375227825Stheravenvoid 376227825Stheraven__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 377227825Stheraven{ 378227825Stheraven while (true) 379227825Stheraven { 380227825Stheraven switch (__i) 381227825Stheraven { 382227825Stheraven case 0: 383227825Stheraven { 384227825Stheraven unique_lock<_L0> __u0(__l0); 385227825Stheraven __i = try_lock(__l1, __l2, __l3...); 386227825Stheraven if (__i == -1) 387227825Stheraven { 388227825Stheraven __u0.release(); 389227825Stheraven return; 390227825Stheraven } 391227825Stheraven } 392227825Stheraven ++__i; 393227825Stheraven sched_yield(); 394227825Stheraven break; 395227825Stheraven case 1: 396227825Stheraven { 397227825Stheraven unique_lock<_L1> __u1(__l1); 398227825Stheraven __i = try_lock(__l2, __l3..., __l0); 399227825Stheraven if (__i == -1) 400227825Stheraven { 401227825Stheraven __u1.release(); 402227825Stheraven return; 403227825Stheraven } 404227825Stheraven } 405227825Stheraven if (__i == sizeof...(_L3) + 1) 406227825Stheraven __i = 0; 407227825Stheraven else 408227825Stheraven __i += 2; 409227825Stheraven sched_yield(); 410227825Stheraven break; 411227825Stheraven default: 412227825Stheraven __lock_first(__i - 2, __l2, __l3..., __l0, __l1); 413227825Stheraven return; 414227825Stheraven } 415227825Stheraven } 416227825Stheraven} 417227825Stheraven 418227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 419227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 420227825Stheravenvoid 421227825Stheravenlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 422227825Stheraven{ 423227825Stheraven __lock_first(0, __l0, __l1, __l2, __l3...); 424227825Stheraven} 425227825Stheraven 426227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 427227825Stheraven 428227825Stheravenstruct once_flag; 429227825Stheraven 430227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 431227825Stheraven 432227825Stheraventemplate<class _Callable, class... _Args> 433227825Stheraven void call_once(once_flag&, _Callable&&, _Args&&...); 434227825Stheraven 435227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 436227825Stheraven 437227825Stheraventemplate<class _Callable> 438227825Stheraven void call_once(once_flag&, _Callable); 439227825Stheraven 440227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 441227825Stheraven 442227825Stheravenstruct _LIBCPP_VISIBLE once_flag 443227825Stheraven{ 444227825Stheraven _LIBCPP_INLINE_VISIBILITY 445227825Stheraven // constexpr 446227825Stheraven once_flag() {} 447227825Stheraven 448227825Stheravenprivate: 449227825Stheraven once_flag(const once_flag&); // = delete; 450227825Stheraven once_flag& operator=(const once_flag&); // = delete; 451227825Stheraven 452227825Stheraven unsigned long __state_; 453227825Stheraven 454227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 455227825Stheraven template<class _Callable, class... _Args> 456227825Stheraven friend 457227825Stheraven void call_once(once_flag&, _Callable&&, _Args&&...); 458227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 459227825Stheraven template<class _Callable> 460227825Stheraven friend 461227825Stheraven void call_once(once_flag&, _Callable); 462227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 463227825Stheraven}; 464227825Stheraven 465227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 466227825Stheraven 467232924Stheraventemplate <class _Fp> 468227825Stheravenclass __call_once_param 469227825Stheraven{ 470232924Stheraven _Fp __f_; 471227825Stheravenpublic: 472227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 473227825Stheraven _LIBCPP_INLINE_VISIBILITY 474232924Stheraven explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 475227825Stheraven#else 476227825Stheraven _LIBCPP_INLINE_VISIBILITY 477232924Stheraven explicit __call_once_param(const _Fp& __f) : __f_(__f) {} 478227825Stheraven#endif 479227825Stheraven 480227825Stheraven _LIBCPP_INLINE_VISIBILITY 481227825Stheraven void operator()() 482227825Stheraven { 483232924Stheraven typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; 484227825Stheraven __execute(_Index()); 485227825Stheraven } 486227825Stheraven 487227825Stheravenprivate: 488227825Stheraven template <size_t ..._Indices> 489227825Stheraven _LIBCPP_INLINE_VISIBILITY 490227825Stheraven void __execute(__tuple_indices<_Indices...>) 491227825Stheraven { 492227825Stheraven __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); 493227825Stheraven } 494227825Stheraven}; 495227825Stheraven 496227825Stheraven#else 497227825Stheraven 498232924Stheraventemplate <class _Fp> 499227825Stheravenclass __call_once_param 500227825Stheraven{ 501232924Stheraven _Fp __f_; 502227825Stheravenpublic: 503227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 504227825Stheraven _LIBCPP_INLINE_VISIBILITY 505232924Stheraven explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 506227825Stheraven#else 507227825Stheraven _LIBCPP_INLINE_VISIBILITY 508232924Stheraven explicit __call_once_param(const _Fp& __f) : __f_(__f) {} 509227825Stheraven#endif 510227825Stheraven 511227825Stheraven _LIBCPP_INLINE_VISIBILITY 512227825Stheraven void operator()() 513227825Stheraven { 514227825Stheraven __f_(); 515227825Stheraven } 516227825Stheraven}; 517227825Stheraven 518227825Stheraven#endif 519227825Stheraven 520232924Stheraventemplate <class _Fp> 521227825Stheravenvoid 522227825Stheraven__call_once_proxy(void* __vp) 523227825Stheraven{ 524232924Stheraven __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); 525227825Stheraven (*__p)(); 526227825Stheraven} 527227825Stheraven 528227825Stheravenvoid __call_once(volatile unsigned long&, void*, void(*)(void*)); 529227825Stheraven 530227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 531227825Stheraven 532227825Stheraventemplate<class _Callable, class... _Args> 533227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 534227825Stheravenvoid 535227825Stheravencall_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) 536227825Stheraven{ 537232924Stheraven if (__flag.__state_ != ~0ul) 538227825Stheraven { 539232924Stheraven typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp; 540232924Stheraven __call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)), 541227825Stheraven __decay_copy(_VSTD::forward<_Args>(__args))...)); 542232924Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); 543227825Stheraven } 544227825Stheraven} 545227825Stheraven 546227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 547227825Stheraven 548227825Stheraventemplate<class _Callable> 549227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 550227825Stheravenvoid 551227825Stheravencall_once(once_flag& __flag, _Callable __func) 552227825Stheraven{ 553227825Stheraven if (__flag.__state_ != ~0ul) 554227825Stheraven { 555227825Stheraven __call_once_param<_Callable> __p(__func); 556227825Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); 557227825Stheraven } 558227825Stheraven} 559227825Stheraven 560227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 561227825Stheraven 562227825Stheraven_LIBCPP_END_NAMESPACE_STD 563227825Stheraven 564227825Stheraven#endif // _LIBCPP_MUTEX 565