mutex revision 278724
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: 23241903Sdim 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(); 47241903Sdim 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(); 82241903Sdim 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; 117241903Sdim unique_lock() noexcept; 118227825Stheraven explicit unique_lock(mutex_type& m); 119241903Sdim 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 131241903Sdim unique_lock(unique_lock&& u) noexcept; 132241903Sdim 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 144241903Sdim void swap(unique_lock& u) noexcept; 145241903Sdim mutex_type* release() noexcept; 146227825Stheraven 147241903Sdim bool owns_lock() const noexcept; 148241903Sdim explicit operator bool () const noexcept; 149241903Sdim mutex_type* mutex() const noexcept; 150227825Stheraven}; 151227825Stheraven 152227825Stheraventemplate <class Mutex> 153241903Sdim 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{ 162241903Sdim 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> 178227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 179227825Stheraven#include <tuple> 180227825Stheraven#endif 181278724Sdim#include <sched.h> 182227825Stheraven 183232950Stheraven#include <__undef_min_max> 184232950Stheraven 185227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 186227825Stheraven#pragma GCC system_header 187227825Stheraven#endif 188227825Stheraven 189227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD 190227825Stheraven 191278724Sdim#ifndef _LIBCPP_HAS_NO_THREADS 192278724Sdim 193249998Sdimclass _LIBCPP_TYPE_VIS recursive_mutex 194227825Stheraven{ 195227825Stheraven pthread_mutex_t __m_; 196227825Stheraven 197227825Stheravenpublic: 198227825Stheraven recursive_mutex(); 199227825Stheraven ~recursive_mutex(); 200227825Stheraven 201227825Stheravenprivate: 202227825Stheraven recursive_mutex(const recursive_mutex&); // = delete; 203227825Stheraven recursive_mutex& operator=(const recursive_mutex&); // = delete; 204227825Stheraven 205227825Stheravenpublic: 206227825Stheraven void lock(); 207241903Sdim bool try_lock() _NOEXCEPT; 208241903Sdim void unlock() _NOEXCEPT; 209227825Stheraven 210227825Stheraven typedef pthread_mutex_t* native_handle_type; 211227825Stheraven _LIBCPP_INLINE_VISIBILITY 212227825Stheraven native_handle_type native_handle() {return &__m_;} 213227825Stheraven}; 214227825Stheraven 215249998Sdimclass _LIBCPP_TYPE_VIS timed_mutex 216227825Stheraven{ 217227825Stheraven mutex __m_; 218227825Stheraven condition_variable __cv_; 219227825Stheraven bool __locked_; 220227825Stheravenpublic: 221227825Stheraven timed_mutex(); 222227825Stheraven ~timed_mutex(); 223227825Stheraven 224227825Stheravenprivate: 225227825Stheraven timed_mutex(const timed_mutex&); // = delete; 226227825Stheraven timed_mutex& operator=(const timed_mutex&); // = delete; 227227825Stheraven 228227825Stheravenpublic: 229227825Stheraven void lock(); 230241903Sdim bool try_lock() _NOEXCEPT; 231227825Stheraven template <class _Rep, class _Period> 232227825Stheraven _LIBCPP_INLINE_VISIBILITY 233227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 234227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 235227825Stheraven template <class _Clock, class _Duration> 236227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 237241903Sdim void unlock() _NOEXCEPT; 238227825Stheraven}; 239227825Stheraven 240227825Stheraventemplate <class _Clock, class _Duration> 241227825Stheravenbool 242227825Stheraventimed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 243227825Stheraven{ 244227825Stheraven using namespace chrono; 245227825Stheraven unique_lock<mutex> __lk(__m_); 246227825Stheraven bool no_timeout = _Clock::now() < __t; 247227825Stheraven while (no_timeout && __locked_) 248227825Stheraven no_timeout = __cv_.wait_until(__lk, __t) == cv_status::no_timeout; 249227825Stheraven if (!__locked_) 250227825Stheraven { 251227825Stheraven __locked_ = true; 252227825Stheraven return true; 253227825Stheraven } 254227825Stheraven return false; 255227825Stheraven} 256227825Stheraven 257249998Sdimclass _LIBCPP_TYPE_VIS recursive_timed_mutex 258227825Stheraven{ 259227825Stheraven mutex __m_; 260227825Stheraven condition_variable __cv_; 261227825Stheraven size_t __count_; 262227825Stheraven pthread_t __id_; 263227825Stheravenpublic: 264227825Stheraven recursive_timed_mutex(); 265227825Stheraven ~recursive_timed_mutex(); 266227825Stheraven 267227825Stheravenprivate: 268227825Stheraven recursive_timed_mutex(const recursive_timed_mutex&); // = delete; 269227825Stheraven recursive_timed_mutex& operator=(const recursive_timed_mutex&); // = delete; 270227825Stheraven 271227825Stheravenpublic: 272227825Stheraven void lock(); 273241903Sdim bool try_lock() _NOEXCEPT; 274227825Stheraven template <class _Rep, class _Period> 275227825Stheraven _LIBCPP_INLINE_VISIBILITY 276227825Stheraven bool try_lock_for(const chrono::duration<_Rep, _Period>& __d) 277227825Stheraven {return try_lock_until(chrono::steady_clock::now() + __d);} 278227825Stheraven template <class _Clock, class _Duration> 279227825Stheraven bool try_lock_until(const chrono::time_point<_Clock, _Duration>& __t); 280241903Sdim void unlock() _NOEXCEPT; 281227825Stheraven}; 282227825Stheraven 283227825Stheraventemplate <class _Clock, class _Duration> 284227825Stheravenbool 285227825Stheravenrecursive_timed_mutex::try_lock_until(const chrono::time_point<_Clock, _Duration>& __t) 286227825Stheraven{ 287227825Stheraven using namespace chrono; 288227825Stheraven pthread_t __id = pthread_self(); 289227825Stheraven unique_lock<mutex> lk(__m_); 290227825Stheraven if (pthread_equal(__id, __id_)) 291227825Stheraven { 292227825Stheraven if (__count_ == numeric_limits<size_t>::max()) 293227825Stheraven return false; 294227825Stheraven ++__count_; 295227825Stheraven return true; 296227825Stheraven } 297227825Stheraven bool no_timeout = _Clock::now() < __t; 298227825Stheraven while (no_timeout && __count_ != 0) 299227825Stheraven no_timeout = __cv_.wait_until(lk, __t) == cv_status::no_timeout; 300227825Stheraven if (__count_ == 0) 301227825Stheraven { 302227825Stheraven __count_ = 1; 303227825Stheraven __id_ = __id; 304227825Stheraven return true; 305227825Stheraven } 306227825Stheraven return false; 307227825Stheraven} 308227825Stheraven 309227825Stheraventemplate <class _L0, class _L1> 310227825Stheravenint 311227825Stheraventry_lock(_L0& __l0, _L1& __l1) 312227825Stheraven{ 313227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 314227825Stheraven if (__u0.owns_lock()) 315227825Stheraven { 316227825Stheraven if (__l1.try_lock()) 317227825Stheraven { 318227825Stheraven __u0.release(); 319227825Stheraven return -1; 320227825Stheraven } 321227825Stheraven else 322227825Stheraven return 1; 323227825Stheraven } 324227825Stheraven return 0; 325227825Stheraven} 326227825Stheraven 327227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 328227825Stheraven 329227825Stheraventemplate <class _L0, class _L1, class _L2, class... _L3> 330227825Stheravenint 331227825Stheraventry_lock(_L0& __l0, _L1& __l1, _L2& __l2, _L3&... __l3) 332227825Stheraven{ 333227825Stheraven int __r = 0; 334227825Stheraven unique_lock<_L0> __u0(__l0, try_to_lock); 335227825Stheraven if (__u0.owns_lock()) 336227825Stheraven { 337227825Stheraven __r = try_lock(__l1, __l2, __l3...); 338227825Stheraven if (__r == -1) 339227825Stheraven __u0.release(); 340227825Stheraven else 341227825Stheraven ++__r; 342227825Stheraven } 343227825Stheraven return __r; 344227825Stheraven} 345227825Stheraven 346227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 347227825Stheraven 348227825Stheraventemplate <class _L0, class _L1> 349227825Stheravenvoid 350227825Stheravenlock(_L0& __l0, _L1& __l1) 351227825Stheraven{ 352227825Stheraven while (true) 353227825Stheraven { 354227825Stheraven { 355227825Stheraven unique_lock<_L0> __u0(__l0); 356227825Stheraven if (__l1.try_lock()) 357227825Stheraven { 358227825Stheraven __u0.release(); 359227825Stheraven break; 360227825Stheraven } 361227825Stheraven } 362227825Stheraven sched_yield(); 363227825Stheraven { 364227825Stheraven unique_lock<_L1> __u1(__l1); 365227825Stheraven if (__l0.try_lock()) 366227825Stheraven { 367227825Stheraven __u1.release(); 368227825Stheraven break; 369227825Stheraven } 370227825Stheraven } 371227825Stheraven sched_yield(); 372227825Stheraven } 373227825Stheraven} 374227825Stheraven 375227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 376227825Stheraven 377227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 378227825Stheravenvoid 379227825Stheraven__lock_first(int __i, _L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 380227825Stheraven{ 381227825Stheraven while (true) 382227825Stheraven { 383227825Stheraven switch (__i) 384227825Stheraven { 385227825Stheraven case 0: 386227825Stheraven { 387227825Stheraven unique_lock<_L0> __u0(__l0); 388227825Stheraven __i = try_lock(__l1, __l2, __l3...); 389227825Stheraven if (__i == -1) 390227825Stheraven { 391227825Stheraven __u0.release(); 392227825Stheraven return; 393227825Stheraven } 394227825Stheraven } 395227825Stheraven ++__i; 396227825Stheraven sched_yield(); 397227825Stheraven break; 398227825Stheraven case 1: 399227825Stheraven { 400227825Stheraven unique_lock<_L1> __u1(__l1); 401227825Stheraven __i = try_lock(__l2, __l3..., __l0); 402227825Stheraven if (__i == -1) 403227825Stheraven { 404227825Stheraven __u1.release(); 405227825Stheraven return; 406227825Stheraven } 407227825Stheraven } 408227825Stheraven if (__i == sizeof...(_L3) + 1) 409227825Stheraven __i = 0; 410227825Stheraven else 411227825Stheraven __i += 2; 412227825Stheraven sched_yield(); 413227825Stheraven break; 414227825Stheraven default: 415227825Stheraven __lock_first(__i - 2, __l2, __l3..., __l0, __l1); 416227825Stheraven return; 417227825Stheraven } 418227825Stheraven } 419227825Stheraven} 420227825Stheraven 421227825Stheraventemplate <class _L0, class _L1, class _L2, class ..._L3> 422227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 423227825Stheravenvoid 424227825Stheravenlock(_L0& __l0, _L1& __l1, _L2& __l2, _L3& ...__l3) 425227825Stheraven{ 426227825Stheraven __lock_first(0, __l0, __l1, __l2, __l3...); 427227825Stheraven} 428227825Stheraven 429227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 430227825Stheraven 431278724Sdim#endif // !_LIBCPP_HAS_NO_THREADS 432227825Stheraven 433278724Sdimstruct _LIBCPP_TYPE_VIS_ONLY once_flag; 434278724Sdim 435227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 436227825Stheraven 437227825Stheraventemplate<class _Callable, class... _Args> 438241903Sdim_LIBCPP_INLINE_VISIBILITY 439241903Sdimvoid call_once(once_flag&, _Callable&&, _Args&&...); 440227825Stheraven 441227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 442227825Stheraven 443227825Stheraventemplate<class _Callable> 444241903Sdim_LIBCPP_INLINE_VISIBILITY 445241903Sdimvoid call_once(once_flag&, _Callable); 446227825Stheraven 447227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 448227825Stheraven 449262801Sdimstruct _LIBCPP_TYPE_VIS_ONLY once_flag 450227825Stheraven{ 451227825Stheraven _LIBCPP_INLINE_VISIBILITY 452241903Sdim _LIBCPP_CONSTEXPR 453241903Sdim once_flag() _NOEXCEPT : __state_(0) {} 454227825Stheraven 455227825Stheravenprivate: 456227825Stheraven once_flag(const once_flag&); // = delete; 457227825Stheraven once_flag& operator=(const once_flag&); // = delete; 458227825Stheraven 459227825Stheraven unsigned long __state_; 460227825Stheraven 461227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 462227825Stheraven template<class _Callable, class... _Args> 463227825Stheraven friend 464227825Stheraven void call_once(once_flag&, _Callable&&, _Args&&...); 465227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 466227825Stheraven template<class _Callable> 467227825Stheraven friend 468227825Stheraven void call_once(once_flag&, _Callable); 469227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 470227825Stheraven}; 471227825Stheraven 472227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 473227825Stheraven 474232950Stheraventemplate <class _Fp> 475227825Stheravenclass __call_once_param 476227825Stheraven{ 477232950Stheraven _Fp __f_; 478227825Stheravenpublic: 479227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 480227825Stheraven _LIBCPP_INLINE_VISIBILITY 481232950Stheraven explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 482227825Stheraven#else 483227825Stheraven _LIBCPP_INLINE_VISIBILITY 484232950Stheraven explicit __call_once_param(const _Fp& __f) : __f_(__f) {} 485227825Stheraven#endif 486227825Stheraven 487227825Stheraven _LIBCPP_INLINE_VISIBILITY 488227825Stheraven void operator()() 489227825Stheraven { 490232950Stheraven typedef typename __make_tuple_indices<tuple_size<_Fp>::value, 1>::type _Index; 491227825Stheraven __execute(_Index()); 492227825Stheraven } 493227825Stheraven 494227825Stheravenprivate: 495227825Stheraven template <size_t ..._Indices> 496227825Stheraven _LIBCPP_INLINE_VISIBILITY 497227825Stheraven void __execute(__tuple_indices<_Indices...>) 498227825Stheraven { 499227825Stheraven __invoke(_VSTD::move(_VSTD::get<0>(__f_)), _VSTD::move(_VSTD::get<_Indices>(__f_))...); 500227825Stheraven } 501227825Stheraven}; 502227825Stheraven 503227825Stheraven#else 504227825Stheraven 505232950Stheraventemplate <class _Fp> 506227825Stheravenclass __call_once_param 507227825Stheraven{ 508232950Stheraven _Fp __f_; 509227825Stheravenpublic: 510227825Stheraven#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES 511227825Stheraven _LIBCPP_INLINE_VISIBILITY 512232950Stheraven explicit __call_once_param(_Fp&& __f) : __f_(_VSTD::move(__f)) {} 513227825Stheraven#else 514227825Stheraven _LIBCPP_INLINE_VISIBILITY 515232950Stheraven explicit __call_once_param(const _Fp& __f) : __f_(__f) {} 516227825Stheraven#endif 517227825Stheraven 518227825Stheraven _LIBCPP_INLINE_VISIBILITY 519227825Stheraven void operator()() 520227825Stheraven { 521227825Stheraven __f_(); 522227825Stheraven } 523227825Stheraven}; 524227825Stheraven 525227825Stheraven#endif 526227825Stheraven 527232950Stheraventemplate <class _Fp> 528227825Stheravenvoid 529227825Stheraven__call_once_proxy(void* __vp) 530227825Stheraven{ 531232950Stheraven __call_once_param<_Fp>* __p = static_cast<__call_once_param<_Fp>*>(__vp); 532227825Stheraven (*__p)(); 533227825Stheraven} 534227825Stheraven 535262801Sdim_LIBCPP_FUNC_VIS void __call_once(volatile unsigned long&, void*, void(*)(void*)); 536227825Stheraven 537227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS 538227825Stheraven 539227825Stheraventemplate<class _Callable, class... _Args> 540227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 541227825Stheravenvoid 542227825Stheravencall_once(once_flag& __flag, _Callable&& __func, _Args&&... __args) 543227825Stheraven{ 544232950Stheraven if (__flag.__state_ != ~0ul) 545227825Stheraven { 546232950Stheraven typedef tuple<typename decay<_Callable>::type, typename decay<_Args>::type...> _Gp; 547232950Stheraven __call_once_param<_Gp> __p(_Gp(__decay_copy(_VSTD::forward<_Callable>(__func)), 548227825Stheraven __decay_copy(_VSTD::forward<_Args>(__args))...)); 549232950Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Gp>); 550227825Stheraven } 551227825Stheraven} 552227825Stheraven 553227825Stheraven#else // _LIBCPP_HAS_NO_VARIADICS 554227825Stheraven 555227825Stheraventemplate<class _Callable> 556227825Stheraveninline _LIBCPP_INLINE_VISIBILITY 557227825Stheravenvoid 558227825Stheravencall_once(once_flag& __flag, _Callable __func) 559227825Stheraven{ 560227825Stheraven if (__flag.__state_ != ~0ul) 561227825Stheraven { 562227825Stheraven __call_once_param<_Callable> __p(__func); 563227825Stheraven __call_once(__flag.__state_, &__p, &__call_once_proxy<_Callable>); 564227825Stheraven } 565227825Stheraven} 566227825Stheraven 567227825Stheraven#endif // _LIBCPP_HAS_NO_VARIADICS 568227825Stheraven 569227825Stheraven_LIBCPP_END_NAMESPACE_STD 570227825Stheraven 571227825Stheraven#endif // _LIBCPP_MUTEX 572