]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/mutex
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / include / std / mutex
CommitLineData
057bae2c 1// <mutex> -*- C++ -*-
2
f1717362 3// Copyright (C) 2003-2016 Free Software Foundation, Inc.
057bae2c 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
6bc9506f 8// Free Software Foundation; either version 3, or (at your option)
057bae2c 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
6bc9506f 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.
057bae2c 19
6bc9506f 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// <http://www.gnu.org/licenses/>.
057bae2c 24
5846aeac 25/** @file include/mutex
057bae2c 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
0c8766b1 34#if __cplusplus < 201103L
d5ad42a1 35# include <bits/c++0x_warning.h>
34e94b7c 36#else
057bae2c 37
c643ba1a 38#include <tuple>
5cee5730 39#include <chrono>
40#include <exception>
41#include <type_traits>
42#include <functional>
43#include <system_error>
adace2e7 44#include <bits/mutex.h>
45#if ! _GTHREAD_USE_MUTEX_TIMEDLOCK
46# include <condition_variable>
47# include <thread>
48#endif
5cee5730 49
821fd9e8 50#ifdef _GLIBCXX_USE_C99_STDINT_TR1
057bae2c 51
2948dd21 52namespace std _GLIBCXX_VISIBILITY(default)
53{
54_GLIBCXX_BEGIN_NAMESPACE_VERSION
5022cf3f 55
adace2e7 56 /**
57 * @ingroup mutexes
58 * @{
59 */
e472b6e5 60
adace2e7 61#ifdef _GLIBCXX_HAS_GTHREADS
e472b6e5 62
efe25f3e 63 // Common base class for std::recursive_mutex and std::recursive_timed_mutex
e472b6e5 64 class __recursive_mutex_base
65 {
66 protected:
67 typedef __gthread_recursive_mutex_t __native_type;
68
69 __recursive_mutex_base(const __recursive_mutex_base&) = delete;
70 __recursive_mutex_base& operator=(const __recursive_mutex_base&) = delete;
71
72#ifdef __GTHREAD_RECURSIVE_MUTEX_INIT
73 __native_type _M_mutex = __GTHREAD_RECURSIVE_MUTEX_INIT;
74
75 __recursive_mutex_base() = default;
76#else
77 __native_type _M_mutex;
78
79 __recursive_mutex_base()
80 {
81 // XXX EAGAIN, ENOMEM, EPERM, EBUSY(may), EINVAL(may)
82 __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION(&_M_mutex);
83 }
84
85 ~__recursive_mutex_base()
4854adab 86 { __gthread_recursive_mutex_destroy(&_M_mutex); }
e472b6e5 87#endif
88 };
89
91315195 90 /// The standard recursive mutex type.
e472b6e5 91 class recursive_mutex : private __recursive_mutex_base
057bae2c 92 {
93 public:
20deb9d4 94 typedef __native_type* native_handle_type;
057bae2c 95
e472b6e5 96 recursive_mutex() = default;
97 ~recursive_mutex() = default;
31a7dfb0 98
5cee5730 99 recursive_mutex(const recursive_mutex&) = delete;
100 recursive_mutex& operator=(const recursive_mutex&) = delete;
101
1d8371c4 102 void
057bae2c 103 lock()
1d8371c4 104 {
057bae2c 105 int __e = __gthread_recursive_mutex_lock(&_M_mutex);
106
107 // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
16de3083 108 if (__e)
109 __throw_system_error(__e);
057bae2c 110 }
1d8371c4 111
112 bool
77dd3f9e 113 try_lock() noexcept
057bae2c 114 {
4cf7d5b5 115 // XXX EINVAL, EAGAIN, EBUSY
5cee5730 116 return !__gthread_recursive_mutex_trylock(&_M_mutex);
057bae2c 117 }
118
1d8371c4 119 void
057bae2c 120 unlock()
1d8371c4 121 {
4cf7d5b5 122 // XXX EINVAL, EAGAIN, EBUSY
5cee5730 123 __gthread_recursive_mutex_unlock(&_M_mutex);
057bae2c 124 }
125
1d8371c4 126 native_handle_type
16de3083 127 native_handle()
5cee5730 128 { return &_M_mutex; }
057bae2c 129 };
130
7a0b241e 131#if _GTHREAD_USE_MUTEX_TIMEDLOCK
2851d736 132 template<typename _Derived>
133 class __timed_mutex_impl
134 {
135 protected:
2851d736 136 typedef chrono::high_resolution_clock __clock_t;
20deb9d4 137
2851d736 138 template<typename _Rep, typename _Period>
139 bool
140 _M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
141 {
4ca82f85 142 using chrono::steady_clock;
143 auto __rt = chrono::duration_cast<steady_clock::duration>(__rtime);
144 if (ratio_greater<steady_clock::period, _Period>())
2851d736 145 ++__rt;
4ca82f85 146 return _M_try_lock_until(steady_clock::now() + __rt);
2851d736 147 }
148
149 template<typename _Duration>
150 bool
151 _M_try_lock_until(const chrono::time_point<__clock_t,
152 _Duration>& __atime)
153 {
4ca82f85 154 auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
155 auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
2851d736 156
157 __gthread_time_t __ts = {
158 static_cast<std::time_t>(__s.time_since_epoch().count()),
159 static_cast<long>(__ns.count())
160 };
161
ae436f3b 162 return static_cast<_Derived*>(this)->_M_timedlock(__ts);
2851d736 163 }
164
165 template<typename _Clock, typename _Duration>
166 bool
167 _M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
4ca82f85 168 {
169 auto __rtime = __atime - _Clock::now();
170 return _M_try_lock_until(__clock_t::now() + __rtime);
171 }
2851d736 172 };
173
91315195 174 /// The standard timed mutex type.
2851d736 175 class timed_mutex
176 : private __mutex_base, public __timed_mutex_impl<timed_mutex>
177 {
16de3083 178 public:
20deb9d4 179 typedef __native_type* native_handle_type;
16de3083 180
e472b6e5 181 timed_mutex() = default;
182 ~timed_mutex() = default;
31a7dfb0 183
5cee5730 184 timed_mutex(const timed_mutex&) = delete;
185 timed_mutex& operator=(const timed_mutex&) = delete;
186
187 void
188 lock()
189 {
190 int __e = __gthread_mutex_lock(&_M_mutex);
191
192 // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
193 if (__e)
194 __throw_system_error(__e);
195 }
196
197 bool
77dd3f9e 198 try_lock() noexcept
5cee5730 199 {
200 // XXX EINVAL, EAGAIN, EBUSY
201 return !__gthread_mutex_trylock(&_M_mutex);
202 }
16de3083 203
204 template <class _Rep, class _Period>
205 bool
5cee5730 206 try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
2851d736 207 { return _M_try_lock_for(__rtime); }
16de3083 208
209 template <class _Clock, class _Duration>
210 bool
5cee5730 211 try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
2851d736 212 { return _M_try_lock_until(__atime); }
5cee5730 213
214 void
215 unlock()
216 {
217 // XXX EINVAL, EAGAIN, EBUSY
218 __gthread_mutex_unlock(&_M_mutex);
219 }
16de3083 220
221 native_handle_type
222 native_handle()
5cee5730 223 { return &_M_mutex; }
ae436f3b 224
225 private:
226 friend class __timed_mutex_impl<timed_mutex>;
227
228 bool
229 _M_timedlock(const __gthread_time_t& __ts)
230 { return !__gthread_mutex_timedlock(&_M_mutex, &__ts); }
16de3083 231 };
232
233 /// recursive_timed_mutex
2851d736 234 class recursive_timed_mutex
235 : private __recursive_mutex_base,
236 public __timed_mutex_impl<recursive_timed_mutex>
16de3083 237 {
238 public:
20deb9d4 239 typedef __native_type* native_handle_type;
5cee5730 240
e472b6e5 241 recursive_timed_mutex() = default;
242 ~recursive_timed_mutex() = default;
31a7dfb0 243
5cee5730 244 recursive_timed_mutex(const recursive_timed_mutex&) = delete;
245 recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
246
247 void
248 lock()
249 {
250 int __e = __gthread_recursive_mutex_lock(&_M_mutex);
251
252 // EINVAL, EAGAIN, EBUSY, EINVAL, EDEADLK(may)
253 if (__e)
254 __throw_system_error(__e);
255 }
16de3083 256
5cee5730 257 bool
77dd3f9e 258 try_lock() noexcept
5cee5730 259 {
260 // XXX EINVAL, EAGAIN, EBUSY
261 return !__gthread_recursive_mutex_trylock(&_M_mutex);
262 }
16de3083 263
264 template <class _Rep, class _Period>
265 bool
5cee5730 266 try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
2851d736 267 { return _M_try_lock_for(__rtime); }
16de3083 268
269 template <class _Clock, class _Duration>
270 bool
5cee5730 271 try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
2851d736 272 { return _M_try_lock_until(__atime); }
5cee5730 273
274 void
275 unlock()
276 {
277 // XXX EINVAL, EAGAIN, EBUSY
278 __gthread_recursive_mutex_unlock(&_M_mutex);
279 }
16de3083 280
281 native_handle_type
282 native_handle()
5cee5730 283 { return &_M_mutex; }
ae436f3b 284
285 private:
286 friend class __timed_mutex_impl<recursive_timed_mutex>;
287
288 bool
289 _M_timedlock(const __gthread_time_t& __ts)
290 { return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts); }
16de3083 291 };
057bae2c 292
adace2e7 293#else // !_GTHREAD_USE_MUTEX_TIMEDLOCK
057bae2c 294
adace2e7 295 /// timed_mutex
296 class timed_mutex
297 {
298 mutex _M_mut;
299 condition_variable _M_cv;
300 bool _M_locked = false;
057bae2c 301
adace2e7 302 public:
057bae2c 303
adace2e7 304 timed_mutex() = default;
6b5e6f09 305 ~timed_mutex() { __glibcxx_assert( !_M_locked ); }
5cee5730 306
adace2e7 307 timed_mutex(const timed_mutex&) = delete;
308 timed_mutex& operator=(const timed_mutex&) = delete;
057bae2c 309
adace2e7 310 void
311 lock()
057bae2c 312 {
adace2e7 313 unique_lock<mutex> __lk(_M_mut);
314 _M_cv.wait(__lk, [&]{ return !_M_locked; });
315 _M_locked = true;
316 }
20deb9d4 317
adace2e7 318 bool
319 try_lock()
320 {
321 lock_guard<mutex> __lk(_M_mut);
322 if (_M_locked)
323 return false;
324 _M_locked = true;
325 return true;
326 }
057bae2c 327
adace2e7 328 template<typename _Rep, typename _Period>
329 bool
330 try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
1d8371c4 331 {
adace2e7 332 unique_lock<mutex> __lk(_M_mut);
333 if (!_M_cv.wait_for(__lk, __rtime, [&]{ return !_M_locked; }))
334 return false;
335 _M_locked = true;
336 return true;
057bae2c 337 }
1d8371c4 338
adace2e7 339 template<typename _Clock, typename _Duration>
340 bool
341 try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
057bae2c 342 {
adace2e7 343 unique_lock<mutex> __lk(_M_mut);
344 if (!_M_cv.wait_until(__lk, __atime, [&]{ return !_M_locked; }))
345 return false;
346 _M_locked = true;
347 return true;
057bae2c 348 }
349
adace2e7 350 void
351 unlock()
352 {
353 lock_guard<mutex> __lk(_M_mut);
6b5e6f09 354 __glibcxx_assert( _M_locked );
adace2e7 355 _M_locked = false;
356 _M_cv.notify_one();
357 }
358 };
057bae2c 359
adace2e7 360 /// recursive_timed_mutex
361 class recursive_timed_mutex
362 {
363 mutex _M_mut;
364 condition_variable _M_cv;
365 thread::id _M_owner;
366 unsigned _M_count = 0;
057bae2c 367
adace2e7 368 // Predicate type that tests whether the current thread can lock a mutex.
369 struct _Can_lock
370 {
adace2e7 371 // Returns true if the mutex is unlocked or is locked by _M_caller.
372 bool
373 operator()() const noexcept
374 { return _M_mx->_M_count == 0 || _M_mx->_M_owner == _M_caller; }
5cee5730 375
adace2e7 376 const recursive_timed_mutex* _M_mx;
377 thread::id _M_caller;
378 };
5cee5730 379
adace2e7 380 public:
20deb9d4 381
adace2e7 382 recursive_timed_mutex() = default;
6b5e6f09 383 ~recursive_timed_mutex() { __glibcxx_assert( _M_count == 0 ); }
057bae2c 384
adace2e7 385 recursive_timed_mutex(const recursive_timed_mutex&) = delete;
386 recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;
20deb9d4 387
adace2e7 388 void
389 lock()
390 {
26befabf 391 auto __id = this_thread::get_id();
392 _Can_lock __can_lock{this, __id};
adace2e7 393 unique_lock<mutex> __lk(_M_mut);
394 _M_cv.wait(__lk, __can_lock);
395 if (_M_count == -1u)
396 __throw_system_error(EAGAIN); // [thread.timedmutex.recursive]/3
397 _M_owner = __id;
398 ++_M_count;
399 }
400
401 bool
402 try_lock()
403 {
26befabf 404 auto __id = this_thread::get_id();
405 _Can_lock __can_lock{this, __id};
adace2e7 406 lock_guard<mutex> __lk(_M_mut);
407 if (!__can_lock())
408 return false;
409 if (_M_count == -1u)
410 return false;
411 _M_owner = __id;
412 ++_M_count;
413 return true;
414 }
057bae2c 415
adace2e7 416 template<typename _Rep, typename _Period>
417 bool
418 try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
1d8371c4 419 {
26befabf 420 auto __id = this_thread::get_id();
421 _Can_lock __can_lock{this, __id};
adace2e7 422 unique_lock<mutex> __lk(_M_mut);
26befabf 423 if (!_M_cv.wait_for(__lk, __rtime, __can_lock))
adace2e7 424 return false;
425 if (_M_count == -1u)
426 return false;
427 _M_owner = __id;
428 ++_M_count;
429 return true;
057bae2c 430 }
431
adace2e7 432 template<typename _Clock, typename _Duration>
1d8371c4 433 bool
adace2e7 434 try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
1d8371c4 435 {
26befabf 436 auto __id = this_thread::get_id();
437 _Can_lock __can_lock{this, __id};
adace2e7 438 unique_lock<mutex> __lk(_M_mut);
26befabf 439 if (!_M_cv.wait_until(__lk, __atime, __can_lock))
adace2e7 440 return false;
441 if (_M_count == -1u)
442 return false;
443 _M_owner = __id;
444 ++_M_count;
445 return true;
057bae2c 446 }
447
adace2e7 448 void
449 unlock()
450 {
451 lock_guard<mutex> __lk(_M_mut);
6b5e6f09 452 __glibcxx_assert( _M_owner == this_thread::get_id() );
453 __glibcxx_assert( _M_count > 0 );
adace2e7 454 if (--_M_count == 0)
20deb9d4 455 {
adace2e7 456 _M_owner = {};
457 _M_cv.notify_one();
5cee5730 458 }
adace2e7 459 }
460 };
20deb9d4 461
adace2e7 462#endif
463#endif // _GLIBCXX_HAS_GTHREADS
057bae2c 464
64c88a3a 465 template<typename _Lock>
b49122a5 466 inline unique_lock<_Lock>
64c88a3a 467 __try_to_lock(_Lock& __l)
b49122a5 468 { return unique_lock<_Lock>{__l, try_to_lock}; }
64c88a3a 469
c643ba1a 470 template<int _Idx, bool _Continue = true>
471 struct __try_lock_impl
472 {
473 template<typename... _Lock>
64c88a3a 474 static void
475 __do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
20deb9d4 476 {
64c88a3a 477 __idx = _Idx;
b49122a5 478 auto __lock = std::__try_to_lock(std::get<_Idx>(__locks));
64c88a3a 479 if (__lock.owns_lock())
480 {
b49122a5 481 constexpr bool __cont = _Idx + 2 < sizeof...(_Lock);
482 using __try_locker = __try_lock_impl<_Idx + 1, __cont>;
483 __try_locker::__do_try_lock(__locks, __idx);
64c88a3a 484 if (__idx == -1)
485 __lock.release();
486 }
c643ba1a 487 }
488 };
20deb9d4 489
c643ba1a 490 template<int _Idx>
491 struct __try_lock_impl<_Idx, false>
492 {
493 template<typename... _Lock>
64c88a3a 494 static void
495 __do_try_lock(tuple<_Lock&...>& __locks, int& __idx)
20deb9d4 496 {
64c88a3a 497 __idx = _Idx;
b49122a5 498 auto __lock = std::__try_to_lock(std::get<_Idx>(__locks));
64c88a3a 499 if (__lock.owns_lock())
500 {
501 __idx = -1;
502 __lock.release();
503 }
c643ba1a 504 }
505 };
20deb9d4 506
c643ba1a 507 /** @brief Generic try_lock.
508 * @param __l1 Meets Mutex requirements (try_lock() may throw).
509 * @param __l2 Meets Mutex requirements (try_lock() may throw).
510 * @param __l3 Meets Mutex requirements (try_lock() may throw).
20deb9d4 511 * @return Returns -1 if all try_lock() calls return true. Otherwise returns
c643ba1a 512 * a 0-based index corresponding to the argument that returned false.
513 * @post Either all arguments are locked, or none will be.
514 *
515 * Sequentially calls try_lock() on each argument.
516 */
517 template<typename _Lock1, typename _Lock2, typename... _Lock3>
1d8371c4 518 int
c643ba1a 519 try_lock(_Lock1& __l1, _Lock2& __l2, _Lock3&... __l3)
520 {
64c88a3a 521 int __idx;
522 auto __locks = std::tie(__l1, __l2, __l3...);
25ca0d61 523 __try_lock_impl<0>::__do_try_lock(__locks, __idx);
64c88a3a 524 return __idx;
c643ba1a 525 }
057bae2c 526
64c88a3a 527 /** @brief Generic lock.
528 * @param __l1 Meets Mutex requirements (try_lock() may throw).
529 * @param __l2 Meets Mutex requirements (try_lock() may throw).
530 * @param __l3 Meets Mutex requirements (try_lock() may throw).
531 * @throw An exception thrown by an argument's lock() or try_lock() member.
532 * @post All arguments are locked.
533 *
534 * All arguments are locked via a sequence of calls to lock(), try_lock()
535 * and unlock(). If the call exits via an exception any locks that were
536 * obtained will be released.
537 */
b49122a5 538 template<typename _L1, typename _L2, typename... _L3>
1d8371c4 539 void
64c88a3a 540 lock(_L1& __l1, _L2& __l2, _L3&... __l3)
541 {
542 while (true)
543 {
b49122a5 544 using __try_locker = __try_lock_impl<0, sizeof...(_L3) != 0>;
64c88a3a 545 unique_lock<_L1> __first(__l1);
546 int __idx;
547 auto __locks = std::tie(__l2, __l3...);
b49122a5 548 __try_locker::__do_try_lock(__locks, __idx);
64c88a3a 549 if (__idx == -1)
550 {
551 __first.release();
552 return;
553 }
554 }
555 }
057bae2c 556
821fd9e8 557#ifdef _GLIBCXX_HAS_GTHREADS
057bae2c 558 /// once_flag
1d8371c4 559 struct once_flag
057bae2c 560 {
20deb9d4 561 private:
057bae2c 562 typedef __gthread_once_t __native_type;
5cebcec7 563 __native_type _M_once = __GTHREAD_ONCE_INIT;
057bae2c 564
20deb9d4 565 public:
8fdae870 566 /// Constructor
5cebcec7 567 constexpr once_flag() noexcept = default;
20deb9d4 568
8fdae870 569 /// Deleted copy constructor
5cee5730 570 once_flag(const once_flag&) = delete;
8fdae870 571 /// Deleted assignment operator
5cee5730 572 once_flag& operator=(const once_flag&) = delete;
057bae2c 573
5cee5730 574 template<typename _Callable, typename... _Args>
575 friend void
7746395b 576 call_once(once_flag& __once, _Callable&& __f, _Args&&... __args);
057bae2c 577 };
578
5cee5730 579#ifdef _GLIBCXX_HAVE_TLS
580 extern __thread void* __once_callable;
581 extern __thread void (*__once_call)();
582
583 template<typename _Callable>
20deb9d4 584 inline void
9e57b7da 585 __once_call_impl()
5cee5730 586 {
587 (*(_Callable*)__once_callable)();
588 }
589#else
590 extern function<void()> __once_functor;
9e57b7da 591
975b5573 592 extern void
593 __set_once_functor_lock_ptr(unique_lock<mutex>*);
594
595 extern mutex&
596 __get_once_mutex();
5cee5730 597#endif
598
ea1cf1e5 599 extern "C" void __once_proxy(void);
5cee5730 600
97a32de0 601 /// call_once
057bae2c 602 template<typename _Callable, typename... _Args>
1d8371c4 603 void
7746395b 604 call_once(once_flag& __once, _Callable&& __f, _Args&&... __args)
057bae2c 605 {
5cee5730 606#ifdef _GLIBCXX_HAVE_TLS
339db54b 607 auto __bound_functor = std::__bind_simple(std::forward<_Callable>(__f),
7746395b 608 std::forward<_Args>(__args)...);
b49122a5 609 __once_callable = std::__addressof(__bound_functor);
5cee5730 610 __once_call = &__once_call_impl<decltype(__bound_functor)>;
611#else
975b5573 612 unique_lock<mutex> __functor_lock(__get_once_mutex());
33ff7935 613 auto __callable = std::__bind_simple(std::forward<_Callable>(__f),
7746395b 614 std::forward<_Args>(__args)...);
33ff7935 615 __once_functor = [&]() { __callable(); };
975b5573 616 __set_once_functor_lock_ptr(&__functor_lock);
5cee5730 617#endif
20deb9d4 618
1e496136 619 int __e = __gthread_once(&__once._M_once, &__once_proxy);
5cee5730 620
5c758b83 621#ifndef _GLIBCXX_HAVE_TLS
622 if (__functor_lock)
975b5573 623 __set_once_functor_lock_ptr(0);
5c758b83 624#endif
625
1d8371c4 626 if (__e)
057bae2c 627 __throw_system_error(__e);
628 }
821fd9e8 629#endif // _GLIBCXX_HAS_GTHREADS
97a32de0 630
631 // @} group mutexes
2948dd21 632_GLIBCXX_END_NAMESPACE_VERSION
633} // namespace
821fd9e8 634#endif // _GLIBCXX_USE_C99_STDINT_TR1
5cee5730 635
0c8766b1 636#endif // C++11
057bae2c 637
34e94b7c 638#endif // _GLIBCXX_MUTEX