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