diff mbox

Fix shared_timed_mutex::try_lock_until() et al

Message ID 20150408193808.GR9755@redhat.com
State New
Headers show

Commit Message

Jonathan Wakely April 8, 2015, 7:38 p.m. UTC
On 08/04/15 20:11 +0100, Jonathan Wakely wrote:
>We can get rid of the _Mutex type then, and just use std::mutex, and
>that also means we can provide the timed locking functions even when
>!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK).
>
>And so maybe we should use this fallback implementation instead of the
>pthread_rwlock_t one when !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK), so
>that they have a complete std::shared_timed_mutex (this applies to at
>least Darwin, not sure which other targets).

Here's a further patch to do that (which really needs to go into 5.0
too, so we don't switch Darwin to the new pthread_rwlock_t version and
then have to swtich it back again in 6.0).

Comments

Torvald Riegel April 10, 2015, 12:16 a.m. UTC | #1
On Wed, 2015-04-08 at 20:38 +0100, Jonathan Wakely wrote:
> On 08/04/15 20:11 +0100, Jonathan Wakely wrote:
> >We can get rid of the _Mutex type then, and just use std::mutex, and
> >that also means we can provide the timed locking functions even when
> >!defined(_GTHREAD_USE_MUTEX_TIMEDLOCK).
> >
> >And so maybe we should use this fallback implementation instead of
> the
> >pthread_rwlock_t one when !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK), so
> >that they have a complete std::shared_timed_mutex (this applies to at
> >least Darwin, not sure which other targets).
> 
> Here's a further patch to do that (which really needs to go into 5.0
> too, so we don't switch Darwin to the new pthread_rwlock_t version and
> then have to swtich it back again in 6.0).

I understand why a mutex with timeouts isn't required anymore, but why
do you now add it to the USE_PTHREAD_RWLOCK_T condition?  If
pthread_rwlock_t is available, why would we need a normal mutex with
timeouts?

For example, this chunk here (and others too):

> diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc
> ++-v3/include/std/shared_mutex
> index 7f26465..351a4f6 100644
> --- a/libstdc++-v3/include/std/shared_mutex
> +++ b/libstdc++-v3/include/std/shared_mutex
> @@ -57,7 +57,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>    /// shared_timed_mutex
>    class shared_timed_mutex
>    {
> -#ifdef _GLIBCXX_USE_PTHREAD_RWLOCK_T
> +#if defined(_GLIBCXX_USE_PTHREAD_RWLOCK_T) &&
> _GTHREAD_USE_MUTEX_TIMEDLOCK
>      typedef chrono::system_clock       __clock_t;
>  
>  #ifdef PTHREAD_RWLOCK_INITIALIZER
Jonathan Wakely April 10, 2015, 8:37 a.m. UTC | #2
On 10/04/15 02:16 +0200, Torvald Riegel wrote:
>On Wed, 2015-04-08 at 20:38 +0100, Jonathan Wakely wrote:
>> On 08/04/15 20:11 +0100, Jonathan Wakely wrote:
>> >We can get rid of the _Mutex type then, and just use std::mutex,
>> >and that also means we can provide the timed locking functions
>> >even when !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK).
>> >
>> >And so maybe we should use this fallback implementation instead of
>> the
>> >pthread_rwlock_t one when !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK),
>> >so that they have a complete std::shared_timed_mutex (this applies
>> >to at least Darwin, not sure which other targets).
>>
>> Here's a further patch to do that (which really needs to go into
>> 5.0 too, so we don't switch Darwin to the new pthread_rwlock_t
>> version and then have to swtich it back again in 6.0).
>
>I understand why a mutex with timeouts isn't required anymore, but
>why do you now add it to the USE_PTHREAD_RWLOCK_T condition?  If
>pthread_rwlock_t is available, why would we need a normal mutex with
>timeouts?

Darwin and HPUX support pthread_rwlock_t but not the timed lock
functions, see https://gcc.gnu.org/PR64847 and (part of)
https://gcc.gnu.org/PR64368 which were "fixed" by
https://gcc.gnu.org/r220161 which just disables the timed lock
functions on those targets, using #if _GTHREAD_USE_MUTEX_TIMEDLOCK.

That means Darwin and HPUX have an incomplete shared_timed_mutex that
doesn't support the timed functions (i.e. what might get added to
C++17 as std::shared_mutex).

The patch below gives Darwin and HPUX a fully conforming (albeit
slower) shared_timed_mutex, by ensuring we don't use pthread_rwlock_t
for targets that can't use timed functions with pthread_rwlock_t.

If std::shared_mutex is added to the standard we could use
pthread_rwlock_t for that even on Darwin and HPUX, because it provides
everything needed for a non-timed std::shared_mutex.

>For example, this chunk here (and others too):
>
>> diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc
>> ++-v3/include/std/shared_mutex
>> index 7f26465..351a4f6 100644
>> --- a/libstdc++-v3/include/std/shared_mutex
>> +++ b/libstdc++-v3/include/std/shared_mutex
>> @@ -57,7 +57,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>    /// shared_timed_mutex
>>    class shared_timed_mutex
>>    {
>> -#ifdef _GLIBCXX_USE_PTHREAD_RWLOCK_T
>> +#if defined(_GLIBCXX_USE_PTHREAD_RWLOCK_T) &&
>> _GTHREAD_USE_MUTEX_TIMEDLOCK
>>      typedef chrono::system_clock       __clock_t;
>>
>>  #ifdef PTHREAD_RWLOCK_INITIALIZER
>
Torvald Riegel April 10, 2015, 9:56 a.m. UTC | #3
On Fri, 2015-04-10 at 09:37 +0100, Jonathan Wakely wrote:
> On 10/04/15 02:16 +0200, Torvald Riegel wrote:
> >On Wed, 2015-04-08 at 20:38 +0100, Jonathan Wakely wrote:
> >> On 08/04/15 20:11 +0100, Jonathan Wakely wrote:
> >> >We can get rid of the _Mutex type then, and just use std::mutex,
> >> >and that also means we can provide the timed locking functions
> >> >even when !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK).
> >> >
> >> >And so maybe we should use this fallback implementation instead of
> >> the
> >> >pthread_rwlock_t one when !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK),
> >> >so that they have a complete std::shared_timed_mutex (this applies
> >> >to at least Darwin, not sure which other targets).
> >>
> >> Here's a further patch to do that (which really needs to go into
> >> 5.0 too, so we don't switch Darwin to the new pthread_rwlock_t
> >> version and then have to swtich it back again in 6.0).
> >
> >I understand why a mutex with timeouts isn't required anymore, but
> >why do you now add it to the USE_PTHREAD_RWLOCK_T condition?  If
> >pthread_rwlock_t is available, why would we need a normal mutex with
> >timeouts?
> 
> Darwin and HPUX support pthread_rwlock_t but not the timed lock
> functions, see https://gcc.gnu.org/PR64847 and (part of)
> https://gcc.gnu.org/PR64368 which were "fixed" by
> https://gcc.gnu.org/r220161 which just disables the timed lock
> functions on those targets, using #if _GTHREAD_USE_MUTEX_TIMEDLOCK.
> 
> That means Darwin and HPUX have an incomplete shared_timed_mutex that
> doesn't support the timed functions (i.e. what might get added to
> C++17 as std::shared_mutex).
> 
> The patch below gives Darwin and HPUX a fully conforming (albeit
> slower) shared_timed_mutex, by ensuring we don't use pthread_rwlock_t
> for targets that can't use timed functions with pthread_rwlock_t.
> 
> If std::shared_mutex is added to the standard we could use
> pthread_rwlock_t for that even on Darwin and HPUX, because it provides
> everything needed for a non-timed std::shared_mutex.

Ah, right.  I was confused by the name, thinking those targets don't
support pthread_mutex_timedlock, not pthread_rwlock_timedrdlock etc.
Jonathan Wakely April 10, 2015, 10:21 a.m. UTC | #4
On 10/04/15 11:56 +0200, Torvald Riegel wrote:
>Ah, right.  I was confused by the name, thinking those targets don't
>support pthread_mutex_timedlock, not pthread_rwlock_timedrdlock etc.

The macro actually relates to the _POSIX_TIMEOUTS macro, but was
originally added to check for pthread_mutex_timedlock support, hence
its name. Maybe a better name would be _GLIBCXX_USE_MUTEX_TIMEOUTS.

Both pthread_mutex_timedlock and pthread_rwlock_timed??lock were
originally part of the POSIX Timeouts option, so on older POSIX
systems they are only available when _POSIX_TIMEOUTS is defined.
(They are part of the base spec in the current POSIX standard, but
Darwin and HPUX don't implement that and still treat them as
optional.)
diff mbox

Patch

commit 20f08d3eac6ec88c83becb8f0cb2e65c10d3fe20
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Apr 8 20:25:45 2015 +0100

    	* include/std/shared_mutex (shared_timed_mutex): Only use
    	pthread_rwlock_t when the POSIX Timeouts option is supported.
    	* testsuite/30_threads/shared_lock/cons/5.cc: Remove
    	dg-require-gthreads-timed.
    	* testsuite/30_threads/shared_lock/cons/6.cc: Likewise.
    	* testsuite/30_threads/shared_lock/locking/3.cc: Likewise.
    	* testsuite/30_threads/shared_lock/locking/4.cc: Likewise.

diff --git a/libstdc++-v3/include/std/shared_mutex b/libstdc++-v3/include/std/shared_mutex
index 7f26465..351a4f6 100644
--- a/libstdc++-v3/include/std/shared_mutex
+++ b/libstdc++-v3/include/std/shared_mutex
@@ -57,7 +57,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
   /// shared_timed_mutex
   class shared_timed_mutex
   {
-#ifdef _GLIBCXX_USE_PTHREAD_RWLOCK_T
+#if defined(_GLIBCXX_USE_PTHREAD_RWLOCK_T) && _GTHREAD_USE_MUTEX_TIMEDLOCK
     typedef chrono::system_clock	__clock_t;
 
 #ifdef PTHREAD_RWLOCK_INITIALIZER
@@ -116,7 +116,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return true;
     }
 
-#if _GTHREAD_USE_MUTEX_TIMEDLOCK
     template<typename _Rep, typename _Period>
       bool
       try_lock_for(const chrono::duration<_Rep, _Period>& __rel_time)
@@ -158,7 +157,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	const auto __s_atime = __s_entry + __delta;
 	return try_lock_until(__s_atime);
       }
-#endif
 
     void
     unlock()
@@ -200,7 +198,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return true;
     }
 
-#if _GTHREAD_USE_MUTEX_TIMEDLOCK
     template<typename _Rep, typename _Period>
       bool
       try_lock_shared_for(const chrono::duration<_Rep, _Period>& __rel_time)
@@ -258,7 +255,6 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	const auto __s_atime = __s_entry + __delta;
 	return try_lock_shared_until(__s_atime);
       }
-#endif
 
     void
     unlock_shared()
@@ -266,7 +262,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
       unlock();
     }
 
-#else // ! _GLIBCXX_USE_PTHREAD_RWLOCK_T
+#else // ! (_GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK)
 
     // Must use the same clock as condition_variable
     typedef chrono::system_clock	__clock_t;
@@ -459,7 +455,7 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    _M_gate1.notify_one();
 	}
     }
-#endif // ! _GLIBCXX_USE_PTHREAD_RWLOCK_T
+#endif // _GLIBCXX_USE_PTHREAD_RWLOCK_T && _GTHREAD_USE_MUTEX_TIMEDLOCK
   };
 #endif // _GLIBCXX_HAS_GTHREADS
 
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/5.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/5.cc
index 63ab514..9ec0498 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/5.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/5.cc
@@ -3,7 +3,6 @@ 
 // { dg-options " -std=gnu++14 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++14 " { target *-*-cygwin *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2013-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/6.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/6.cc
index 8b2bcd5..2074bbe 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_lock/cons/6.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/cons/6.cc
@@ -3,7 +3,6 @@ 
 // { dg-options " -std=gnu++14 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++14 " { target *-*-cygwin *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2013-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/3.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/3.cc
index b67022a..4b653ea 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/3.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/3.cc
@@ -3,7 +3,6 @@ 
 // { dg-options " -std=gnu++14 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++14 " { target *-*-cygwin *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2013-2015 Free Software Foundation, Inc.
 //
diff --git a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/4.cc b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/4.cc
index e87d0dd..afeefa2 100644
--- a/libstdc++-v3/testsuite/30_threads/shared_lock/locking/4.cc
+++ b/libstdc++-v3/testsuite/30_threads/shared_lock/locking/4.cc
@@ -3,7 +3,6 @@ 
 // { dg-options " -std=gnu++14 -pthreads" { target *-*-solaris* } }
 // { dg-options " -std=gnu++14 " { target *-*-cygwin *-*-darwin* } }
 // { dg-require-cstdint "" }
-// { dg-require-gthreads-timed "" }
 
 // Copyright (C) 2013-2015 Free Software Foundation, Inc.
 //