summaryrefslogtreecommitdiffstats
path: root/libstdc++-v3/include/std/mutex
diff options
context:
space:
mode:
authorredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-18 22:55:02 +0000
committerredi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-18 22:55:02 +0000
commit2851d736ebf1e8cceebb9106cab69d2c3fdc7624 (patch)
treec491d5047a720ef9b19dbe186747c2ab31667949 /libstdc++-v3/include/std/mutex
parent3bc4161a6a4610c91897d637c64dfd50003455ba (diff)
downloadppe42-gcc-2851d736ebf1e8cceebb9106cab69d2c3fdc7624.tar.gz
ppe42-gcc-2851d736ebf1e8cceebb9106cab69d2c3fdc7624.zip
PR libstdc++/57641
* include/std/mutex (timed_mutex, recursive_timed_mutex): Move common functionality to new __timed_mutex_impl mixin. Overload try_lock_until to handle conversion between different clocks. Replace constrained __try_lock_for_impl overloads with conditional increment. * include/std/shared_mutex (shared_mutex::_Mutex): Use the new mixin. * testsuite/30_threads/timed_mutex/try_lock_until/57641.cc: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200180 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/std/mutex')
-rw-r--r--libstdc++-v3/include/std/mutex142
1 files changed, 54 insertions, 88 deletions
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index cdd05a37cbe..40b2e31dc7f 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -199,15 +199,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
- /// timed_mutex
- class timed_mutex : private __mutex_base
- {
+ template<typename _Derived>
+ class __timed_mutex_impl
+ {
+ protected:
#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
- typedef chrono::steady_clock __clock_t;
+ typedef chrono::steady_clock __clock_t;
#else
- typedef chrono::high_resolution_clock __clock_t;
+ typedef chrono::high_resolution_clock __clock_t;
#endif
+ template<typename _Rep, typename _Period>
+ bool
+ _M_try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
+ {
+ auto __rt = chrono::duration_cast<__clock_t::duration>(__rtime);
+ if (ratio_greater<__clock_t::period, _Period>())
+ ++__rt;
+
+ return _M_try_lock_until(__clock_t::now() + __rt);
+ }
+
+ template<typename _Duration>
+ bool
+ _M_try_lock_until(const chrono::time_point<__clock_t,
+ _Duration>& __atime)
+ {
+ chrono::time_point<__clock_t, chrono::seconds> __s =
+ chrono::time_point_cast<chrono::seconds>(__atime);
+
+ chrono::nanoseconds __ns =
+ chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ __gthread_time_t __ts = {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
+
+ auto __mutex = static_cast<_Derived*>(this)->native_handle();
+ return !__gthread_mutex_timedlock(__mutex, &__ts);
+ }
+
+ template<typename _Clock, typename _Duration>
+ bool
+ _M_try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
+ { return _M_try_lock_for(__atime - _Clock::now()); }
+ };
+
+ /// timed_mutex
+ class timed_mutex
+ : private __mutex_base, public __timed_mutex_impl<timed_mutex>
+ {
public:
typedef __native_type* native_handle_type;
@@ -237,25 +279,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <class _Rep, class _Period>
bool
try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
- { return __try_lock_for_impl(__rtime); }
+ { return _M_try_lock_for(__rtime); }
template <class _Clock, class _Duration>
bool
try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
- {
- chrono::time_point<_Clock, chrono::seconds> __s =
- chrono::time_point_cast<chrono::seconds>(__atime);
-
- chrono::nanoseconds __ns =
- chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
-
- __gthread_time_t __ts = {
- static_cast<std::time_t>(__s.time_since_epoch().count()),
- static_cast<long>(__ns.count())
- };
-
- return !__gthread_mutex_timedlock(&_M_mutex, &__ts);
- }
+ { return _M_try_lock_until(__atime); }
void
unlock()
@@ -267,40 +296,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
native_handle_type
native_handle()
{ return &_M_mutex; }
-
- private:
- template<typename _Rep, typename _Period>
- typename enable_if<
- ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
- __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
- {
- __clock_t::time_point __atime = __clock_t::now()
- + chrono::duration_cast<__clock_t::duration>(__rtime);
-
- return try_lock_until(__atime);
- }
-
- template <typename _Rep, typename _Period>
- typename enable_if<
- !ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
- __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
- {
- __clock_t::time_point __atime = __clock_t::now()
- + ++chrono::duration_cast<__clock_t::duration>(__rtime);
-
- return try_lock_until(__atime);
- }
};
/// recursive_timed_mutex
- class recursive_timed_mutex : private __recursive_mutex_base
+ class recursive_timed_mutex
+ : private __recursive_mutex_base,
+ public __timed_mutex_impl<recursive_timed_mutex>
{
-#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
- typedef chrono::steady_clock __clock_t;
-#else
- typedef chrono::high_resolution_clock __clock_t;
-#endif
-
public:
typedef __native_type* native_handle_type;
@@ -330,25 +332,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <class _Rep, class _Period>
bool
try_lock_for(const chrono::duration<_Rep, _Period>& __rtime)
- { return __try_lock_for_impl(__rtime); }
+ { return _M_try_lock_for(__rtime); }
template <class _Clock, class _Duration>
bool
try_lock_until(const chrono::time_point<_Clock, _Duration>& __atime)
- {
- chrono::time_point<_Clock, chrono::seconds> __s =
- chrono::time_point_cast<chrono::seconds>(__atime);
-
- chrono::nanoseconds __ns =
- chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
-
- __gthread_time_t __ts = {
- static_cast<std::time_t>(__s.time_since_epoch().count()),
- static_cast<long>(__ns.count())
- };
-
- return !__gthread_recursive_mutex_timedlock(&_M_mutex, &__ts);
- }
+ { return _M_try_lock_until(__atime); }
void
unlock()
@@ -360,29 +349,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
native_handle_type
native_handle()
{ return &_M_mutex; }
-
- private:
- template<typename _Rep, typename _Period>
- typename enable_if<
- ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
- __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
- {
- __clock_t::time_point __atime = __clock_t::now()
- + chrono::duration_cast<__clock_t::duration>(__rtime);
-
- return try_lock_until(__atime);
- }
-
- template <typename _Rep, typename _Period>
- typename enable_if<
- !ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
- __try_lock_for_impl(const chrono::duration<_Rep, _Period>& __rtime)
- {
- __clock_t::time_point __atime = __clock_t::now()
- + ++chrono::duration_cast<__clock_t::duration>(__rtime);
-
- return try_lock_until(__atime);
- }
};
#endif
#endif // _GLIBCXX_HAS_GTHREADS
OpenPOWER on IntegriCloud