OpenCores
URL https://opencores.org/ocsvn/altor32/altor32/trunk

Subversion Repositories altor32

[/] [altor32/] [trunk/] [gcc-x64/] [or1knd-elf/] [or1knd-elf/] [include/] [c++/] [4.8.0/] [mutex] - Blame information for rev 35

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 ultra_embe
//  -*- C++ -*-
2
 
3
// Copyright (C) 2003-2012 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 3, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// Under Section 7 of GPL version 3, you are granted additional
17
// permissions described in the GCC Runtime Library Exception, version
18
// 3.1, as published by the Free Software Foundation.
19
 
20
// You should have received a copy of the GNU General Public License and
21
// a copy of the GCC Runtime Library Exception along with this program;
22
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23
// .
24
 
25
/** @file include/mutex
26
 *  This is a Standard C++ Library header.
27
 */
28
 
29
#ifndef _GLIBCXX_MUTEX
30
#define _GLIBCXX_MUTEX 1
31
 
32
#pragma GCC system_header
33
 
34
#if __cplusplus < 201103L
35
# include 
36
#else
37
 
38
#include 
39
#include 
40
#include 
41
#include 
42
#include 
43
#include 
44
#include 
45
#include 
46
#include  // for std::swap
47
 
48
#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
49
 
50
namespace std _GLIBCXX_VISIBILITY(default)
51
{
52
_GLIBCXX_BEGIN_NAMESPACE_VERSION
53
 
54
  // Common base class for std::mutex and std::timed_mutex
55
  class __mutex_base
56
  {
57
  protected:
58
    typedef __gthread_mutex_t                   __native_type;
59
 
60
#ifdef __GTHREAD_MUTEX_INIT
61
    __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;
62
 
63
    constexpr __mutex_base() noexcept = default;
64
#else
65
    __native_type  _M_mutex;
66
 
67
    __mutex_base() noexcept
68
    {
69
      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
70
      __GTHREAD_MUTEX_INIT_FUNCTION(&_M_mutex);
71
    }
72
 
73
    ~__mutex_base() noexcept { __gthread_mutex_destroy(&_M_mutex); }
74
#endif
75
 
76
    __mutex_base(const __mutex_base&) = delete;
77
    __mutex_base& operator=(const __mutex_base&) = delete;
78
  };
79
 
80
  // Common base class for std::recursive_mutex and std::timed_recursive_mutex
81
  class __recursive_mutex_base
82
  {
83
  protected:
84
    typedef __gthread_recursive_mutex_t         __native_type;
85
 
86
    __recursive_mutex_base(const __recursive_mutex_base&) = delete;
87
    __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete;
88
 
89
#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
90
    __native_type  _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;
91
 
92
    __recursive_mutex_base() = default;
93
#else
94
    __native_type  _M_mutex;
95
 
96
    __recursive_mutex_base()
97
    {
98
      // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
99
      __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
100
    }
101
 
102
    ~__recursive_mutex_base()
103
    { __gthread_recursive_mutex_destroy(&_M_mutex); }
104
#endif
105
  };
106
 
107
  /**
108
   * @defgroup mutexes Mutexes
109
   * @ingroup concurrency
110
   *
111
   * Classes for mutex support.
112
   * @{
113
   */
114
 
115
  /// mutex
116
  class mutex : private __mutex_base
117
  {
118
  public:
119
    typedef __native_type*                      native_handle_type;
120
 
121
#ifdef __GTHREAD_MUTEX_INIT
122
    constexpr
123
#endif
124
    mutex() noexcept = default;
125
    ~mutex() = default;
126
 
127
    mutex(const mutex&) = delete;
128
    mutex& operator=(const mutex&) = delete;
129
 
130
    void
131
    lock()
132
    {
133
      int __e = __gthread_mutex_lock(&_M_mutex);
134
 
135
      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
136
      if (__e)
137
        __throw_system_error(__e);
138
    }
139
 
140
    bool
141
    try_lock() noexcept
142
    {
143
      // XXX EINVAL, EAGAIN, EBUSY
144
      return !__gthread_mutex_trylock(&_M_mutex);
145
    }
146
 
147
    void
148
    unlock()
149
    {
150
      // XXX EINVAL, EAGAIN, EPERM
151
      __gthread_mutex_unlock(&_M_mutex);
152
    }
153
 
154
    native_handle_type
155
    native_handle()
156
    { return &_M_mutex; }
157
  };
158
 
159
  /// recursive_mutex
160
  class recursive_mutex : private __recursive_mutex_base
161
  {
162
  public:
163
    typedef __native_type*                      native_handle_type;
164
 
165
    recursive_mutex() = default;
166
    ~recursive_mutex() = default;
167
 
168
    recursive_mutex(const recursive_mutex&) = delete;
169
    recursive_mutex& operator=(const recursive_mutex&) = delete;
170
 
171
    void
172
    lock()
173
    {
174
      int __e = __gthread_recursive_mutex_lock(&_M_mutex);
175
 
176
      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
177
      if (__e)
178
        __throw_system_error(__e);
179
    }
180
 
181
    bool
182
    try_lock() noexcept
183
    {
184
      // XXX EINVAL, EAGAIN, EBUSY
185
      return !__gthread_recursive_mutex_trylock(&_M_mutex);
186
    }
187
 
188
    void
189
    unlock()
190
    {
191
      // XXX EINVAL, EAGAIN, EBUSY
192
      __gthread_recursive_mutex_unlock(&_M_mutex);
193
    }
194
 
195
    native_handle_type
196
    native_handle()
197
    { return &_M_mutex; }
198
  };
199
 
200
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
201
  /// timed_mutex
202
  class timed_mutex : private __mutex_base
203
  {
204
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
205
    typedef chrono::steady_clock                __clock_t;
206
#else
207
    typedef chrono::high_resolution_clock       __clock_t;
208
#endif
209
 
210
  public:
211
    typedef __native_type*                      native_handle_type;
212
 
213
    timed_mutex() = default;
214
    ~timed_mutex() = default;
215
 
216
    timed_mutex(const timed_mutex&) = delete;
217
    timed_mutex& operator=(const timed_mutex&) = delete;
218
 
219
    void
220
    lock()
221
    {
222
      int __e = __gthread_mutex_lock(&_M_mutex);
223
 
224
      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
225
      if (__e)
226
        __throw_system_error(__e);
227
    }
228
 
229
    bool
230
    try_lock() noexcept
231
    {
232
      // XXX EINVAL, EAGAIN, EBUSY
233
      return !__gthread_mutex_trylock(&_M_mutex);
234
    }
235
 
236
    template 
237
      bool
238
      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
239
      { return __try_lock_for_impl(__rtime); }
240
 
241
    template 
242
      bool
243
      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
244
      {
245
        chrono::time_point<_Clock, chrono::seconds> __s =
246
          chrono::time_point_cast(__atime);
247
 
248
        chrono::nanoseconds __ns =
249
          chrono::duration_cast(__atime - __s);
250
 
251
        __gthread_time_t __ts = {
252
          static_cast(__s.time_since_epoch().count()),
253
          static_cast(__ns.count())
254
        };
255
 
256
        return !__gthread_mutex_timedlock(&_M_mutex, &__ts);
257
      }
258
 
259
    void
260
    unlock()
261
    {
262
      // XXX EINVAL, EAGAIN, EBUSY
263
      __gthread_mutex_unlock(&_M_mutex);
264
    }
265
 
266
    native_handle_type
267
    native_handle()
268
    { return &_M_mutex; }
269
 
270
  private:
271
    template
272
      typename enable_if<
273
        ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
274
      __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
275
      {
276
        __clock_t::time_point __atime = __clock_t::now()
277
          + chrono::duration_cast<__clock_t::duration>(__rtime);
278
 
279
        return try_lock_until(__atime);
280
      }
281
 
282
    template 
283
      typename enable_if<
284
        !ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
285
      __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
286
      {
287
        __clock_t::time_point __atime = __clock_t::now()
288
          + ++chrono::duration_cast<__clock_t::duration>(__rtime);
289
 
290
        return try_lock_until(__atime);
291
      }
292
  };
293
 
294
  /// recursive_timed_mutex
295
  class recursive_timed_mutex : private __recursive_mutex_base
296
  {
297
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
298
    typedef chrono::steady_clock                __clock_t;
299
#else
300
    typedef chrono::high_resolution_clock       __clock_t;
301
#endif
302
 
303
  public:
304
    typedef __native_type*                      native_handle_type;
305
 
306
    recursive_timed_mutex() = default;
307
    ~recursive_timed_mutex() = default;
308
 
309
    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
310
    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
311
 
312
    void
313
    lock()
314
    {
315
      int __e = __gthread_recursive_mutex_lock(&_M_mutex);
316
 
317
      // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
318
      if (__e)
319
        __throw_system_error(__e);
320
    }
321
 
322
    bool
323
    try_lock() noexcept
324
    {
325
      // XXX EINVAL, EAGAIN, EBUSY
326
      return !__gthread_recursive_mutex_trylock(&_M_mutex);
327
    }
328
 
329
    template 
330
      bool
331
      try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
332
      { return __try_lock_for_impl(__rtime); }
333
 
334
    template 
335
      bool
336
      try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
337
      {
338
        chrono::time_point<_Clock, chrono::seconds>  __s =
339
          chrono::time_point_cast(__atime);
340
 
341
        chrono::nanoseconds __ns =
342
          chrono::duration_cast(__atime - __s);
343
 
344
        __gthread_time_t __ts = {
345
          static_cast(__s.time_since_epoch().count()),
346
          static_cast(__ns.count())
347
        };
348
 
349
        return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts);
350
      }
351
 
352
    void
353
    unlock()
354
    {
355
      // XXX EINVAL, EAGAIN, EBUSY
356
      __gthread_recursive_mutex_unlock(&_M_mutex);
357
    }
358
 
359
    native_handle_type
360
    native_handle()
361
    { return &_M_mutex; }
362
 
363
  private:
364
    template
365
      typename enable_if<
366
        ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
367
      __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
368
      {
369
        __clock_t::time_point __atime = __clock_t::now()
370
          + chrono::duration_cast<__clock_t::duration>(__rtime);
371
 
372
        return try_lock_until(__atime);
373
      }
374
 
375
    template 
376
      typename enable_if<
377
        !ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
378
      __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
379
      {
380
        __clock_t::time_point __atime = __clock_t::now()
381
          + ++chrono::duration_cast<__clock_t::duration>(__rtime);
382
 
383
        return try_lock_until(__atime);
384
      }
385
  };
386
#endif
387
 
388
  /// Do not acquire ownership of the mutex.
389
  struct defer_lock_t { };
390
 
391
  /// Try to acquire ownership of the mutex without blocking.
392
  struct try_to_lock_t { };
393
 
394
  /// Assume the calling thread has already obtained mutex ownership
395
  /// and manage it.
396
  struct adopt_lock_t { };
397
 
398
  constexpr defer_lock_t        defer_lock { };
399
  constexpr try_to_lock_t       try_to_lock { };
400
  constexpr adopt_lock_t        adopt_lock { };
401
 
402
  /// @brief  Scoped lock idiom.
403
  // Acquire the mutex here with a constructor call, then release with
404
  // the destructor call in accordance with RAII style.
405
  template
406
    class lock_guard
407
    {
408
    public:
409
      typedef _Mutex mutex_type;
410
 
411
      explicit lock_guard(mutex_type& __m) : _M_device(__m)
412
      { _M_device.lock(); }
413
 
414
      lock_guard(mutex_type& __m, adopt_lock_t) : _M_device(__m)
415
      { } // calling thread owns mutex
416
 
417
      ~lock_guard()
418
      { _M_device.unlock(); }
419
 
420
      lock_guard(const lock_guard&) = delete;
421
      lock_guard& operator=(const lock_guard&) = delete;
422
 
423
    private:
424
      mutex_type&  _M_device;
425
    };
426
 
427
  /// unique_lock
428
  template
429
    class unique_lock
430
    {
431
    public:
432
      typedef _Mutex mutex_type;
433
 
434
      unique_lock() noexcept
435
      : _M_device(0), _M_owns(false)
436
      { }
437
 
438
      explicit unique_lock(mutex_type& __m)
439
      : _M_device(&__m), _M_owns(false)
440
      {
441
        lock();
442
        _M_owns = true;
443
      }
444
 
445
      unique_lock(mutex_type& __m, defer_lock_t) noexcept
446
      : _M_device(&__m), _M_owns(false)
447
      { }
448
 
449
      unique_lock(mutex_type& __m, try_to_lock_t)
450
      : _M_device(&__m), _M_owns(_M_device->try_lock())
451
      { }
452
 
453
      unique_lock(mutex_type& __m, adopt_lock_t)
454
      : _M_device(&__m), _M_owns(true)
455
      {
456
        // XXX calling thread owns mutex
457
      }
458
 
459
      template
460
        unique_lock(mutex_type& __m,
461
                    const chrono::time_point<_Clock, _Duration>& __atime)
462
        : _M_device(&__m), _M_owns(_M_device->try_lock_until(__atime))
463
        { }
464
 
465
      template
466
        unique_lock(mutex_type& __m,
467
                    const chrono::duration<_Rep, _Period>& __rtime)
468
        : _M_device(&__m), _M_owns(_M_device->try_lock_for(__rtime))
469
        { }
470
 
471
      ~unique_lock()
472
      {
473
        if (_M_owns)
474
          unlock();
475
      }
476
 
477
      unique_lock(const unique_lock&) = delete;
478
      unique_lock& operator=(const unique_lock&) = delete;
479
 
480
      unique_lock(unique_lock&& __u) noexcept
481
      : _M_device(__u._M_device), _M_owns(__u._M_owns)
482
      {
483
        __u._M_device = 0;
484
        __u._M_owns = false;
485
      }
486
 
487
      unique_lock& operator=(unique_lock&& __u) noexcept
488
      {
489
        if(_M_owns)
490
          unlock();
491
 
492
        unique_lock(std::move(__u)).swap(*this);
493
 
494
        __u._M_device = 0;
495
        __u._M_owns = false;
496
 
497
        return *this;
498
      }
499
 
500
      void
501
      lock()
502
      {
503
        if (!_M_device)
504
          __throw_system_error(int(errc::operation_not_permitted));
505
        else if (_M_owns)
506
          __throw_system_error(int(errc::resource_deadlock_would_occur));
507
        else
508
          {
509
            _M_device->lock();
510
            _M_owns = true;
511
          }
512
      }
513
 
514
      bool
515
      try_lock()
516
      {
517
        if (!_M_device)
518
          __throw_system_error(int(errc::operation_not_permitted));
519
        else if (_M_owns)
520
          __throw_system_error(int(errc::resource_deadlock_would_occur));
521
        else
522
          {
523
            _M_owns = _M_device->try_lock();
524
            return _M_owns;
525
          }
526
      }
527
 
528
      template
529
        bool
530
        try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
531
        {
532
          if (!_M_device)
533
            __throw_system_error(int(errc::operation_not_permitted));
534
          else if (_M_owns)
535
            __throw_system_error(int(errc::resource_deadlock_would_occur));
536
          else
537
            {
538
              _M_owns = _M_device->try_lock_until(__atime);
539
              return _M_owns;
540
            }
541
        }
542
 
543
      template
544
        bool
545
        try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
546
        {
547
          if (!_M_device)
548
            __throw_system_error(int(errc::operation_not_permitted));
549
          else if (_M_owns)
550
            __throw_system_error(int(errc::resource_deadlock_would_occur));
551
          else
552
            {
553
              _M_owns = _M_device->try_lock_for(__rtime);
554
              return _M_owns;
555
            }
556
         }
557
 
558
      void
559
      unlock()
560
      {
561
        if (!_M_owns)
562
          __throw_system_error(int(errc::operation_not_permitted));
563
        else if (_M_device)
564
          {
565
            _M_device->unlock();
566
            _M_owns = false;
567
          }
568
      }
569
 
570
      void
571
      swap(unique_lock& __u) noexcept
572
      {
573
        std::swap(_M_device, __u._M_device);
574
        std::swap(_M_owns, __u._M_owns);
575
      }
576
 
577
      mutex_type*
578
      release() noexcept
579
      {
580
        mutex_type* __ret = _M_device;
581
        _M_device = 0;
582
        _M_owns = false;
583
        return __ret;
584
      }
585
 
586
      bool
587
      owns_lock() const noexcept
588
      { return _M_owns; }
589
 
590
      explicit operator bool() const noexcept
591
      { return owns_lock(); }
592
 
593
      mutex_type*
594
      mutex() const noexcept
595
      { return _M_device; }
596
 
597
    private:
598
      mutex_type*       _M_device;
599
      bool              _M_owns; // XXX use atomic_bool
600
    };
601
 
602
  /// Partial specialization for unique_lock objects.
603
  template
604
    inline void
605
    swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>& __y) noexcept
606
    { __x.swap(__y); }
607
 
608
  template
609
    struct __unlock_impl
610
    {
611
      template
612
        static void
613
        __do_unlock(tuple<_Lock&...>& __locks)
614
        {
615
          std::get<_Idx>(__locks).unlock();
616
          __unlock_impl<_Idx - 1>::__do_unlock(__locks);
617
        }
618
    };
619
 
620
  template<>
621
    struct __unlock_impl<-1>
622
    {
623
      template
624
        static void
625
        __do_unlock(tuple<_Lock&...>&)
626
        { }
627
    };
628
 
629
  template
630
    unique_lock<_Lock>
631
    __try_to_lock(_Lock& __l)
632
    { return unique_lock<_Lock>(__l, try_to_lock); }
633
 
634
  template
635
    struct __try_lock_impl
636
    {
637
      template
638
        static void
639
        __do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
640
        {
641
          __idx = _Idx;
642
          auto __lock = __try_to_lock(std::get<_Idx>(__locks));
643
          if (__lock.owns_lock())
644
            {
645
              __try_lock_impl<_Idx + 1, _Idx + 2 < sizeof...(_Lock)>::
646
                __do_try_lock(__locks, __idx);
647
              if (__idx == -1)
648
                __lock.release();
649
            }
650
        }
651
    };
652
 
653
  template
654
    struct __try_lock_impl<_Idx, false>
655
    {
656
      template
657
        static void
658
        __do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
659
        {
660
          __idx = _Idx;
661
          auto __lock = __try_to_lock(std::get<_Idx>(__locks));
662
          if (__lock.owns_lock())
663
            {
664
              __idx = -1;
665
              __lock.release();
666
            }
667
        }
668
    };
669
 
670
  /** @brief Generic try_lock.
671
   *  @param __l1 Meets Mutex requirements (try_lock() may throw).
672
   *  @param __l2 Meets Mutex requirements (try_lock() may throw).
673
   *  @param __l3 Meets Mutex requirements (try_lock() may throw).
674
   *  @return Returns -1 if all try_lock() calls return true. Otherwise returns
675
   *          a 0-based index corresponding to the argument that returned false.
676
   *  @post Either all arguments are locked, or none will be.
677
   *
678
   *  Sequentially calls try_lock() on each argument.
679
   */
680
  template
681
    int
682
    try_lock(_Lock1& __l1, _Lock2& __l2, _Lock3&... __l3)
683
    {
684
      int __idx;
685
      auto __locks = std::tie(__l1, __l2, __l3...);
686
      __try
687
      { __try_lock_impl<0>::__do_try_lock(__locks, __idx); }
688
      __catch(...)
689
      { }
690
      return __idx;
691
    }
692
 
693
  /** @brief Generic lock.
694
   *  @param __l1 Meets Mutex requirements (try_lock() may throw).
695
   *  @param __l2 Meets Mutex requirements (try_lock() may throw).
696
   *  @param __l3 Meets Mutex requirements (try_lock() may throw).
697
   *  @throw An exception thrown by an argument's lock() or try_lock() member.
698
   *  @post All arguments are locked.
699
   *
700
   *  All arguments are locked via a sequence of calls to lock(), try_lock()
701
   *  and unlock().  If the call exits via an exception any locks that were
702
   *  obtained will be released.
703
   */
704
  template
705
    void
706
    lock(_L1& __l1, _L2& __l2, _L3&... __l3)
707
    {
708
      while (true)
709
        {
710
          unique_lock<_L1> __first(__l1);
711
          int __idx;
712
          auto __locks = std::tie(__l2, __l3...);
713
          __try_lock_impl<0, sizeof...(_L3)>::__do_try_lock(__locks, __idx);
714
          if (__idx == -1)
715
            {
716
              __first.release();
717
              return;
718
            }
719
        }
720
    }
721
 
722
  /// once_flag
723
  struct once_flag
724
  {
725
  private:
726
    typedef __gthread_once_t __native_type;
727
    __native_type  _M_once = __GTHREAD_ONCE_INIT;
728
 
729
  public:
730
    /// Constructor
731
    constexpr once_flag() noexcept = default;
732
 
733
    /// Deleted copy constructor
734
    once_flag(const once_flag&) = delete;
735
    /// Deleted assignment operator
736
    once_flag& operator=(const once_flag&) = delete;
737
 
738
    template
739
      friend void
740
      call_once(once_flag& __once, _Callable&& __f, _Args&&... __args);
741
  };
742
 
743
#ifdef _GLIBCXX_HAVE_TLS
744
  extern __thread void* __once_callable;
745
  extern __thread void (*__once_call)();
746
 
747
  template
748
    inline void
749
    __once_call_impl()
750
    {
751
      (*(_Callable*)__once_callable)();
752
    }
753
#else
754
  extern function __once_functor;
755
 
756
  extern void
757
  __set_once_functor_lock_ptr(unique_lock*);
758
 
759
  extern mutex&
760
  __get_once_mutex();
761
#endif
762
 
763
  extern "C" void __once_proxy(void);
764
 
765
  /// call_once
766
  template
767
    void
768
    call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
769
    {
770
#ifdef _GLIBCXX_HAVE_TLS
771
      auto __bound_functor = std::__bind_simple(std::forward<_Callable>(__f),
772
          std::forward<_Args>(__args)...);
773
      __once_callable = &__bound_functor;
774
      __once_call = &__once_call_impl;
775
#else
776
      unique_lock __functor_lock(__get_once_mutex());
777
      auto __callable = std::__bind_simple(std::forward<_Callable>(__f),
778
          std::forward<_Args>(__args)...);
779
      __once_functor = [&]() { __callable(); };
780
      __set_once_functor_lock_ptr(&__functor_lock);
781
#endif
782
 
783
      int __e = __gthread_once(&(__once._M_once), &__once_proxy);
784
 
785
#ifndef _GLIBCXX_HAVE_TLS
786
      if (__functor_lock)
787
        __set_once_functor_lock_ptr(0);
788
#endif
789
 
790
      if (__e)
791
        __throw_system_error(__e);
792
    }
793
 
794
  // @} group mutexes
795
_GLIBCXX_END_NAMESPACE_VERSION
796
} // namespace
797
 
798
#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
799
 
800
#endif // C++11
801
 
802
#endif // _GLIBCXX_MUTEX

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.