Bug 51296 - Several 30_threads tests FAIL on Tru64 UNIX
Summary: Several 30_threads tests FAIL on Tru64 UNIX
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.7.0
: P3 normal
Target Milestone: 4.7.0
Assignee: Rainer Orth
URL: http://gcc.gnu.org/ml/gcc-patches/201...
Keywords:
Depends on:
Blocks:
 
Reported: 2011-11-24 17:54 UTC by Rainer Orth
Modified: 2012-02-10 18:13 UTC (History)
0 users

See Also:
Host: alpha-dec-osf5.1b
Target: alpha-dec-osf5.1b
Build: alpha-dec-osf5.1b
Known to work:
Known to fail:
Last reconfirmed: 2011-11-24 00:00:00


Attachments
proposed patch (853 bytes, patch)
2012-02-03 08:50 UTC, Jonathan Wakely
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Rainer Orth 2011-11-24 17:54:36 UTC
Between 20111021 (r180287) and 20111128 (r180617), several 30_threads tests
started to FAIL on Tru64 UNIX:

FAIL: 30_threads/async/async.cc execution test

terminate called after throwing an instance of 'std::system_error'
  what():  Invalid argument

FAIL: 30_threads/condition_variable/members/1.cc execution test

Assertion failed: false, file /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/30_threads/condition_variable/members/1.cc, line 49

FAIL: 30_threads/condition_variable/members/2.cc execution test

Assertion failed: false, file /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc, line 49

FAIL: 30_threads/condition_variable_any/members/1.cc execution test
FAIL: 30_threads/condition_variable_any/members/2.cc execution test
FAIL: 30_threads/future/cons/constexpr.cc scan-assembler-not _ZNSt6futureIvEC2Ev
FAIL: 30_threads/future/cons/constexpr.cc scan-assembler-not _ZNSt6futureIiEC2Ev
FAIL: 30_threads/lock/1.cc execution test
FAIL: 30_threads/lock/3.cc execution test
FAIL: 30_threads/lock/4.cc execution test
FAIL: 30_threads/mutex/lock/1.cc execution test
FAIL: 30_threads/mutex/try_lock/1.cc execution test
FAIL: 30_threads/mutex/try_lock/2.cc execution test
FAIL: 30_threads/shared_future/cons/constexpr.cc scan-assembler-not _ZNSt13shared_futureIvEC2Ev
FAIL: 30_threads/shared_future/cons/constexpr.cc scan-assembler-not _ZNSt13shared_futureIiEC2Ev
FAIL: 30_threads/thread/native_handle/typesizes.cc execution test
FAIL: 30_threads/try_lock/1.cc execution test
FAIL: 30_threads/try_lock/2.cc execution test
FAIL: 30_threads/try_lock/3.cc execution test
FAIL: 30_threads/try_lock/4.cc execution test
FAIL: 30_threads/unique_lock/cons/2.cc execution test
FAIL: 30_threads/unique_lock/cons/4.cc execution test
FAIL: 30_threads/unique_lock/locking/1.cc execution test
FAIL: 30_threads/unique_lock/locking/2.cc execution test
FAIL: 30_threads/unique_lock/modifiers/1.cc execution test
FAIL: 30_threads/unique_lock/modifiers/2.cc execution test

This may be due to this change:

2011-10-22  Jonathan Wakely  <jwakely.gcc@gmail.com>

        PR libstdc++/50196
        * acinclude.m4 (GLIBCXX_HAS_GTHREADS): Don't depend on _POSIX_TIMEOUTS.
        * configure: Regenerate.
        * include/std/mutex (timed_mutex, recursive_timed_mutex): Define

On this platform, _POSIX_TIMEOUTS is missing in <unistd.h>.

I find that those tests are UNSUPPORTED on the 4.6 branch.

  Rainer
Comment 1 Jonathan Wakely 2011-11-24 18:53:29 UTC
The point of that change was to enable C++11 threading on platforms that support Pthreads without the Timeouts option, so the fact the tests now run instead of being UNSUPPORTED is intended.

We could always take alpha*-*-osf* out of the target list, but I'll try to figure out how to make them work on Tru64
Comment 2 Jonathan Wakely 2011-11-24 19:26:23 UTC
(In reply to comment #0)
> FAIL: 30_threads/thread/native_handle/typesizes.cc execution test

This one should definitely not run on Tru64, disabling that is pre-approved.

Is -pthread all that's needed for this platform?
Comment 3 Jonathan Wakely 2011-11-24 20:30:43 UTC
What does this program do, compiled with -std=c++11 -pthread ?

#include <mutex>
#include <system_error>
#include <assert.h>
#define VERIFY assert

int main()
{
  typedef std::mutex mutex_type;
  typedef std::unique_lock<mutex_type> lock_type;

  try
    {
      mutex_type m;
      lock_type lock(m);

      VERIFY( lock.owns_lock() );
      VERIFY( (bool)lock );
    }
  catch (const std::system_error& e)
    {
      VERIFY( false );
    }
  catch (...)
    {
      VERIFY( false );
    }

  return 0;
}
Comment 4 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-25 14:04:26 UTC
> --- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-24 19:26:23 UTC ---
> (In reply to comment #0)
>> FAIL: 30_threads/thread/native_handle/typesizes.cc execution test
>
> This one should definitely not run on Tru64, disabling that is pre-approved.

Ok, thanks.

> Is -pthread all that's needed for this platform?

Yes, should be.

	Rainer
Comment 5 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-25 14:06:10 UTC
> --- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-24 20:30:43 UTC ---
> What does this program do, compiled with -std=c++11 -pthread ?

I get

Assertion failed: false, file thread.cc, line 21
IOT/Abort trap

	Rainer
Comment 6 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-25 14:12:25 UTC
> --- Comment #5 from ro at CeBiTec dot Uni-Bielefeld.DE <ro at CeBiTec dot Uni-Bielefeld.DE> 2011-11-25 14:06:10 UTC ---
>> --- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-24 20:30:43 UTC ---
>> What does this program do, compiled with -std=c++11 -pthread ?
>
> I get
>
> Assertion failed: false, file thread.cc, line 21
> IOT/Abort trap

I've run it under gdb (which has massive problems on that platform right
now), and it seems that in

alpha-dec-osf5.1b/libstdc++-v3/include/mutex:172

____gthread_mutex_lock(&_M_mutex) returns EINVAL.

	Rainer
Comment 7 Jonathan Wakely 2011-11-25 14:46:07 UTC
Thanks for the info - that error implies the mutex was not correctly initialized.

What are these macros defined to (if defined)?

__GTHREAD_MUTEX_INIT
__GTHREAD_MUTEX_INIT
__GTHREAD_MUTEX_INIT_FUNCTION


> FAIL: 30_threads/future/cons/constexpr.cc scan-assembler-not
_ZNSt6futureIvEC2Ev
> FAIL: 30_threads/future/cons/constexpr.cc scan-assembler-not
_ZNSt6futureIiEC2Ev
> FAIL: 30_threads/shared_future/cons/constexpr.cc scan-assembler-not
_ZNSt13shared_futureIvEC2Ev
> FAIL: 30_threads/shared_future/cons/constexpr.cc scan-assembler-not
_ZNSt13shared_futureIiEC2Ev

These errors indicate a front-end problem (failing to do static init for the constexpr constructor) or a bug in the testcase.
Comment 8 Jonathan Wakely 2011-11-25 14:46:37 UTC
(In reply to comment #7)
> __GTHREAD_MUTEX_INIT
> __GTHREAD_MUTEX_INIT

sorry, ignore the double-paste  ;)
Comment 9 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-25 14:57:24 UTC
> --- Comment #7 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-25 14:46:07 UTC ---
> Thanks for the info - that error implies the mutex was not correctly
> initialized.
>
> What are these macros defined to (if defined)?
>
> __GTHREAD_MUTEX_INIT
> __GTHREAD_MUTEX_INIT
> __GTHREAD_MUTEX_INIT_FUNCTION

With -g3 -save-temps, I find

#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER

and

#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MSTATE_CONFIG, _PTHREAD_MVALID | _PTHREAD_MVF_STA}

#define _PTHREAD_MSTATE_CONFIG 0x00200000
#define _PTHREAD_MVALID (0x05bcafe1L)
#define _PTHREAD_MVF_STA 0x08000000L

>> FAIL: 30_threads/future/cons/constexpr.cc scan-assembler-not
> _ZNSt6futureIvEC2Ev
>> FAIL: 30_threads/future/cons/constexpr.cc scan-assembler-not
> _ZNSt6futureIiEC2Ev
>> FAIL: 30_threads/shared_future/cons/constexpr.cc scan-assembler-not
> _ZNSt13shared_futureIvEC2Ev
>> FAIL: 30_threads/shared_future/cons/constexpr.cc scan-assembler-not
> _ZNSt13shared_futureIiEC2Ev
>
> These errors indicate a front-end problem (failing to do static init for the
> constexpr constructor) or a bug in the testcase.

I think it's a testcase bug: for the first case, grep reveals

 #.stabs        "future:Tt4100=s16!1,020,4071;__base_ctor ::4102=#4100,3,4103=*4100,4104=&4105=k4106=4072,3;:_ZNSt6futureIvEC2ERKSt10shared_ptrINSt13__future_base11_State_baseEE;0A.;__comp_ctor ::4102:_ZNSt6futureIvEC1ERKSt10shared_ptrINSt13__future_base11_State_baseEE;0A.;__base_ctor ::4107=#4100,3,4103,3;:_ZNSt6futureIvEC2Ev;2A.;__comp_ctor ::4107:_ZNSt6futureIvEC1Ev;2A.;__base_ctor ::4108=#4100,3,4103,4109=&4110=4100,3;:_ZNSt6futureIvEC2EOS0_;2A.;__comp_ctor ::4108:_ZNSt6futureIvEC1EOS0_;2A.;__base_ctor ::4111=#4100,3,4103,4112=&4113=k4110,3;:_ZNSt6futureIvEC2ERKS0_;2A.;__comp_ctor ::4111:_ZNSt6futureIvEC1ERKS0_;2A.;operator=::4114=#4100,4115=&4110,4103,4112,3;:_ZNSt6futureIvEaSERKS0_;2A.4116=#4100,4115,4103,4109,3;:_ZNSt6futureIvEaSEOS0_;2A.;get::4117=#4100,3,4103,3;:_ZNSt6futureIvE3getEv;2A.;share::4118=#4100,4095,4103,3;:_ZNSt6futureIvE5shareEv;2A.;;",128,0,727,0

With -g0, grep finds nothing else.

	Rainer
Comment 10 Jonathan Wakely 2011-11-25 15:17:09 UTC
ah so the scan-assembler test is finding the stabs info, not actually a call to the constructor
Comment 11 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-25 15:55:36 UTC
> --- Comment #10 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-25 15:17:09 UTC ---
> ah so the scan-assembler test is finding the stabs info, not actually a call to
> the constructor

Right.  I see we already have a few -g0's in constexpr.cc tests:

libstdc++-v3/testsuite/20_util/unique_ptr/cons/constexpr.cc:// { dg-options "-std=gnu++0x -fno-inline -save-temps -g0" }
libstdc++-v3/testsuite/20_util/shared_ptr/cons/constexpr.cc:// { dg-options "-std=gnu++0x -fno-inline -save-temps -g0" }
libstdc++-v3/testsuite/20_util/weak_ptr/cons/constexpr.cc:// { dg-options "-std=gnu++0x -fno-inline -save-temps -g0" }
libstdc++-v3/testsuite/20_util/enable_shared_from_this/cons/constexpr.cc:// { dg-options "-std=gnu++0x -fno-inline -save-temps -g0" }

This was done for PR libstdc++/46869, the same issue.

	Rainer
Comment 12 Jonathan Wakely 2011-11-26 15:15:26 UTC
Author: redi
Date: Sat Nov 26 15:15:22 2011
New Revision: 181740

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=181740
Log:
	PR libstdc++/51296
	* testsuite/30_threads/thread/native_handle/typesizes.cc: Do not run
	on alpha*-*-osf*.
	* testsuite/30_threads/future/cons/constexpr.cc: Disable debug
	symbols.
	* testsuite/30_threads/shared_future/cons/constexpr.cc: Likewise.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/testsuite/30_threads/future/cons/constexpr.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/constexpr.cc
    trunk/libstdc++-v3/testsuite/30_threads/thread/native_handle/typesizes.cc
Comment 13 Jonathan Wakely 2011-11-26 15:18:40 UTC
Does this reduced test work with -std=gnu++11 -pthread ?

#include <stdio.h>
#include <string.h>
#include <pthread.h>

struct M {
  pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
  constexpr M() noexcept = default;
};

int main()
{
   M m;
   int e = pthread_mutex_lock(&m.m);
   if (e)
     printf("%d : %s\n", e, strerror(e));
   return e;
}
Comment 14 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-28 12:42:17 UTC
> --- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-26 15:18:40 UTC ---
> Does this reduced test work with -std=gnu++11 -pthread ?

Unfortunately not, I still get

22 : Invalid argument

Only if I add an explicit call to pthread_mutex_init does the testcase
work.

I've no real idea why this happens.  pthread_mutex_init(3) states

  Use the PTHREAD_MUTEX_INITIALIZER macro to statically initialize a mutex
  without calling this routine. Statically initialized mutexes need not be
  destroyed using pthread_mutex_destroy(3). Use this macro as follows:

  pthread_mutex_t mutex= PTHREAD_MUTEX_INITIALIZER

  Only normal mutexes can be statically initialized.

While I do have Tru64 UNIX sources, libpthread is only partially
included and the implementation of pthread_mutex_lock is missing.

	Rainer
Comment 15 Jonathan Wakely 2011-11-28 14:22:24 UTC
(In reply to comment #14)
> > --- Comment #13 from Jonathan Wakely <redi at gcc dot gnu.org> 2011-11-26 15:18:40 UTC ---
> > Does this reduced test work with -std=gnu++11 -pthread ?
> 
> Unfortunately not, I still get
> 
> 22 : Invalid argument

IMHO it's fortunate since it's not just problem in the std::mutex code ;)

> Only if I add an explicit call to pthread_mutex_init does the testcase
> work.

Very strange, especially since the definitions you gave in comment 9 don't seem to do anything complicated.

Does this work?

#include <stdio.h>
#include <string.h>
#include <pthread.h>

struct M {
  pthread_mutex_t m;
  M() noexcept {
       pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER;
       m = tmp;
  }
};

int main()
{
   M m;
   int e = pthread_mutex_lock(&m.m);
   if (e)
     printf("%d : %s\n", e, strerror(e));
   return e;
}

If that works, we might be able to fix it using fixincludes (similar to PR 50982 comment 32)

Otherwise I suppose we must not define __GTHREAD_MUTEX_INIT on Tru64, causing std::mutex to use the init function instead.
Comment 16 ro@CeBiTec.Uni-Bielefeld.DE 2011-11-28 14:34:38 UTC
> Does this work?

No, I still get EINVAL.

> Otherwise I suppose we must not define __GTHREAD_MUTEX_INIT on Tru64, causing
> std::mutex to use the init function instead.

The strange thing is that is seems to have worked so far without issues,
e.g. in emutls.c.

	Rainer
Comment 17 Jonathan Wakely 2011-11-28 14:40:21 UTC
(In reply to comment #16)
> The strange thing is that is seems to have worked so far without issues,
> e.g. in emutls.c.

and in libstdc++-v3/include/ext/concurrence.h

maybe the difference is -std=c++11
Comment 18 Jonathan Wakely 2012-01-11 16:50:09 UTC
Regarding the remaining failures, it appears to be a front-end issue. Fixing it in the library could be done with an autoconf macro to detect that the testcase in comment 13 works. If that macro isn't defined, use the init function instead of the init macro.

I'm not sure if/when I'll be able to work on that.
Comment 19 ro@CeBiTec.Uni-Bielefeld.DE 2012-01-11 17:37:59 UTC
> --- Comment #18 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-01-11 16:50:09 UTC ---
> Regarding the remaining failures, it appears to be a front-end issue. Fixing it
> in the library could be done with an autoconf macro to detect that the testcase
> in comment 13 works. If that macro isn't defined, use the init function instead
> of the init macro.

I've just tried it with the vendor cxx (first disabling noexcept for C++
< 2011), and it also fails with EINVAL.

> I'm not sure if/when I'll be able to work on that.

Given that this is mostly autoconf work, I could give it a try myself if
I can figure out where best to override the __GTHREAD_MUTEX_INIT
definition from gthr-default.h/gthr-posix.h.  The problem seems to be
that autoconf results go into <bits/c++config.h>, which is included way
before <bits/gthr.h>.

If all else failed, one could do so in libgcc/gthr-posix.h.

	Rainer
Comment 20 Jonathan Wakely 2012-01-11 17:48:25 UTC
(In reply to comment #19)
> I've just tried it with the vendor cxx (first disabling noexcept for C++
> < 2011), and it also fails with EINVAL.

Well that's something vaguely positive at least ... the root cause probably isn't a G++ front-end issue or libstdc++ issue.
 
> > I'm not sure if/when I'll be able to work on that.
> 
> Given that this is mostly autoconf work, I could give it a try myself if
> I can figure out where best to override the __GTHREAD_MUTEX_INIT
> definition from gthr-default.h/gthr-posix.h.  The problem seems to be
> that autoconf results go into <bits/c++config.h>, which is included way
> before <bits/gthr.h>.

Yes, that's why I thought of making it depend on some new _GLIBCXX_BROKEN_GTHREAD_MUTEX_INIT macro set in <bits/c++config.h> by autoconf, rather trying to alter gthr-posix.h

then e.g.

   class __mutex_base
   {
   protected:
     typedef __gthread_mutex_t           __native_type;

-#ifdef __GTHREAD_MUTEX_INIT
-#if defined __GTHREAD_MUTEX_INIT && !defined _GLIBCXX_BROKEN_GTHREAD_MUTEX_INIT
     __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;

     constexpr __mutex_base() noexcept = default;
#else
     __native_type  _M_mutex;
Comment 21 ro@CeBiTec.Uni-Bielefeld.DE 2012-01-12 15:47:53 UTC
> --- Comment #20 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-01-11 17:48:25 UTC ---
> (In reply to comment #19)
>> I've just tried it with the vendor cxx (first disabling noexcept for C++
>> < 2011), and it also fails with EINVAL.
>
> Well that's something vaguely positive at least ... the root cause probably
> isn't a G++ front-end issue or libstdc++ issue.

True, though I still don't understand why it wouldn't work in C++ when a
similar C testcase does.

>> Given that this is mostly autoconf work, I could give it a try myself if
>> I can figure out where best to override the __GTHREAD_MUTEX_INIT
>> definition from gthr-default.h/gthr-posix.h.  The problem seems to be
>> that autoconf results go into <bits/c++config.h>, which is included way
>> before <bits/gthr.h>.
>
> Yes, that's why I thought of making it depend on some new
> _GLIBCXX_BROKEN_GTHREAD_MUTEX_INIT macro set in <bits/c++config.h> by autoconf,
> rather trying to alter gthr-posix.h
>
> then e.g.
>
>    class __mutex_base
>    {
>    protected:
>      typedef __gthread_mutex_t           __native_type;
>
> -#ifdef __GTHREAD_MUTEX_INIT
> -#if defined __GTHREAD_MUTEX_INIT && !defined
> _GLIBCXX_BROKEN_GTHREAD_MUTEX_INIT
>      __native_type  _M_mutex = __GTHREAD_MUTEX_INIT;
>
>      constexpr __mutex_base() noexcept = default;
> #else
>      __native_type  _M_mutex;

Unfortunately, we still need to provide __GTHREAD_MUTEX_INIT_FUNCTION,
and it seems best to do so in gthr-posix.h directly, as is done in
gthr-dce.h.  Here's the patch I came up with so far.  gthr-posix.h has
Tru64 UNIX-specific code already, so this isn't much worse that what we
already have.  __GTHREAD_COND_INIT has the same issue, so it needs the
same workaround.

The std/mutex change is a hack to avoid

In file included from /var/gcc/regression/trunk/5.1b-gcc/build/alpha-dec-osf5.1b/libstdc++-v3/include/future:40:0,
                 from /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/30_threads/async/async.cc:27:
/var/gcc/regression/trunk/5.1b-gcc/build/alpha-dec-osf5.1b/libstdc++-v3/include/mutex:160:5: error: function 'std::mutex::mutex()' defaulted on its first declaration with an exception-specification that differs from the implicit declaration 'std::mutex::mutex()'

and the condition_variable.cc change accounts for the fact that gthr.h
only documents __GTHREAD_COND_INIT_FUNCTION (analogous to
__GTHREAD_MUTEX_INIT_FUNCTION), not __gthread_cond_init.

--- gthr-posix.h.dist	Sat Jan  7 00:12:15 2012
+++ gthr-posix.h	Thu Jan 12 13:50:52 2012
@@ -62,7 +62,13 @@ typedef struct timespec __gthread_time_t
    in gthr.h for details. */
 #define __GTHREAD_HAS_COND	1
 
+#ifndef __osf__
 #define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
+#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
+#else
+#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
+#define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
+#endif
 #define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
 #if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
 #define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
@@ -71,7 +77,6 @@ typedef struct timespec __gthread_time_t
 #else
 #define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
 #endif
-#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
 #define __GTHREAD_TIME_INIT {0,0}
 
 #if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
@@ -730,6 +735,20 @@ __gthread_setspecific (__gthread_key_t _
   return __gthrw_(pthread_setspecific) (__key, __ptr);
 }
 
+static inline void
+__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
+{
+  if (__gthread_active_p ())
+    __gthrw_(pthread_mutex_init) (__mutex, NULL);
+}
+
+static inline void
+__gthread_cond_init_function (__gthread_cond_t *__cond)
+{
+  if (__gthread_active_p ())
+    __gthrw_(pthread_cond_init) (__cond, NULL);
+}
+
 static inline int
 __gthread_mutex_destroy (__gthread_mutex_t *__mutex)
 {
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -157,7 +157,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #ifdef __GTHREAD_MUTEX_INIT
     constexpr
 #endif
-    mutex() noexcept = default;
+    //    mutex() noexcept = default;
+    mutex() = default;
     ~mutex() = default;
 
     mutex(const mutex&) = delete;
diff --git a/libstdc++-v3/src/condition_variable.cc b/libstdc++-v3/src/condition_variable.cc
--- a/libstdc++-v3/src/condition_variable.cc
+++ b/libstdc++-v3/src/condition_variable.cc
@@ -36,10 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
   condition_variable::condition_variable() noexcept
   {
-    int __e = __gthread_cond_init(&_M_cond, 0);
-
-    if (__e)
-      __throw_system_error(__e);
+    __GTHREAD_COND_INIT_FUNCTION(&_M_cond);
   }
 
   condition_variable::~condition_variable() noexcept

I've rebuilt libstdc++.so with those changes and am currently rerunning
the testsuite.  The previously failing 30_threads testcases pass now.

Would this approach (with a proper fix in <mutex> instead of the hack)
be appropriate from the C++ view?  I'll include something along this
line in this weekend's bootstrap and see if it causes other problems.

	Rainer
Comment 22 Jonathan Wakely 2012-01-12 16:16:30 UTC
(In reply to comment #21)
> The std/mutex change is a hack to avoid
> 
> In file included from
> /var/gcc/regression/trunk/5.1b-gcc/build/alpha-dec-osf5.1b/libstdc++-v3/include/future:40:0,
>                  from
> /vol/gcc/src/hg/trunk/local/libstdc++-v3/testsuite/30_threads/async/async.cc:27:
> /var/gcc/regression/trunk/5.1b-gcc/build/alpha-dec-osf5.1b/libstdc++-v3/include/mutex:160:5:
> error: function 'std::mutex::mutex()' defaulted on its first declaration with
> an exception-specification that differs from the implicit declaration
> 'std::mutex::mutex()'

Does adding 'noexcept' to ~__mutex_base() make that hack unnecessary?

The destructor should be implicitly noexcept, but G++ doesn't implement that yet (PR 50043) so adding 'noexcept' there is ok.
Comment 23 ro@CeBiTec.Uni-Bielefeld.DE 2012-01-12 18:17:56 UTC
> Does adding 'noexcept' to ~__mutex_base() make that hack unnecessary?
>
> The destructor should be implicitly noexcept, but G++ doesn't implement that
> yet (PR 50043) so adding 'noexcept' there is ok.

Yep, that does the trick.

	Rainer
Comment 24 ro@CeBiTec.Uni-Bielefeld.DE 2012-01-13 10:25:34 UTC
I've done some more digging and found that the EINVAL error is generated
inside libpthread.so, by a function called __thdIsAddrInStack.  And in
fact, if I make M m static, the test passes.

While I do have Tru64 UNIX V5.1 sources, some parts are missing,
libpthread sources unfortunately among them, so I cannot determine why
this is done or suggest another workaround.

	Rainer
Comment 25 Jonathan Wakely 2012-01-13 10:37:52 UTC
Nice digging.  POSIX does say the INIT macro is for use when the mutex is statically-allocated:

"In cases where default mutex attributes are appropriate, the macro PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes that are statically allocated."


For most platforms it works fine for automatic variables and in C++ for member variables too.

Maybe something scans the BSS segment at startup to find mutexes?!  In any case, it looks as though we should definitely use the init function instead of the macro on Tru64.
Comment 26 ro@CeBiTec.Uni-Bielefeld.DE 2012-01-16 18:58:20 UTC
> --- Comment #25 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-01-13 10:37:52 UTC ---
> Nice digging.  POSIX does say the INIT macro is for use when the mutex is
> statically-allocated:
>
> "In cases where default mutex attributes are appropriate, the macro
> PTHREAD_MUTEX_INITIALIZER can be used to initialize mutexes that are statically
> allocated."
>
>
> For most platforms it works fine for automatic variables and in C++ for member
> variables too.
>
> Maybe something scans the BSS segment at startup to find mutexes?!  In any
> case, it looks as though we should definitely use the init function instead of
> the macro on Tru64.

Unfortunately, while my test to do so fixes the 30_threads failures, it
introduced tons of failures elsewhere (both libstdc++ and others).  I
don't fully understand what's happening there, but perhaps we need a fix
in libstdc++ instead, especially given that the use of
PTHREAD_MUTEX_INITIALIZER at hand isn't standard-conforming.

	Rainer
Comment 27 Jonathan Wakely 2012-01-16 19:36:49 UTC
C++11 requires that std::mutex::mutex() is constexpr, so that a global std::mutex will be statically initialized. If that constructor is constexpr it can't call pthread_mutex_init().

But C++11 also requires non-global, non-static mutexes to be possible, so we can't use the PTHREAD_MUTEX_INITIALIZER either.

The option we've taken is to ignore the text I quoted in comment 25 and rely on the macro working for non-statically allocated mutexes, which works on most platforms.
Comment 28 Rainer Orth 2012-01-31 11:40:21 UTC
Author: ro
Date: Tue Jan 31 11:40:17 2012
New Revision: 183754

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183754
Log:
Link C++ tests with -shared-libgcc (PR libitm/51822)

	PR libstdc++/51296
	* testsuite/libitm.c++/c++.exp (lang_link_flags): Add
	-shared-libgcc.
	Correct libgomp references.

Modified:
    trunk/libitm/ChangeLog
    trunk/libitm/testsuite/libitm.c++/c++.exp
Comment 29 Jonathan Wakely 2012-01-31 19:09:00 UTC
(N.B. that ChangeLog entry cited the wrong PR)

The wording quoted in comment 25 is a POSIX defect:
http://austingroupbugs.net/view.php?id=70#c127
Comment 30 ro@CeBiTec.Uni-Bielefeld.DE 2012-02-01 10:23:33 UTC
> --- Comment #29 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-01-31 19:09:00 UTC ---
> (N.B. that ChangeLog entry cited the wrong PR)

I know, I've already corrected the ChangeLog.

> The wording quoted in comment 25 is a POSIX defect:
> http://austingroupbugs.net/view.php?id=70#c127

Ok.  Unfortunately this doesn't help for Tru64 UNIX, which won't change
at this point.  I wonder if we could use pthread_mutex_init() only for
the threads support instead of globally?

Otherwise, we should probably disable it on osf instead of leaving it
broken.

	Rainer
Comment 31 Jonathan Wakely 2012-02-01 10:58:32 UTC
(In reply to comment #30)
> I wonder if we could use pthread_mutex_init() only for
> the threads support instead of globally?

I'll add some extra preprocessor conditions around the mutex init code, so that os_defines.h can force std::mutex to use the init function even if the INIT macro is defined by gthr-posix.h

That should also help for PR 51906
Comment 32 Jonathan Wakely 2012-02-03 08:50:24 UTC
Created attachment 26559 [details]
proposed patch

Since a similar problem exists for darwin11's PTHREAD_RECURSIVE_MUTEX_INITIALIZER this solution is not OSF-specific.  This allows config/os/*/os_defines.h to define one or more of:

_GTHREAD_USE_MUTEX_INIT_FUNC
_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
_GTHREAD_USE_COND_INIT_FUNC

which will cause gthr-posix.h to #undef the INIT macro and define an INIT_FUNCTION instead.  

Would this work here too?  You could either add a config/os/osf/os_defines.h file (which would also need the other files in config/os/generic to be copied for osf) or you could just put this in gthr-posix.h

#ifdef __osf__
# define _GTHREAD_USE_MUTEX_INIT_FUNC
# define _GTHREAD_USE_COND_INIT_FUNC
#endif
Comment 33 Jonathan Wakely 2012-02-03 08:52:17 UTC
Oops, this hunk would be needed too


--- a/libstdc++-v3/src/c++11/condition_variable.cc
+++ b/libstdc++-v3/src/c++11/condition_variable.cc
@@ -36,7 +36,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #else
   condition_variable::condition_variable() noexcept
   {
-    int __e = __gthread_cond_init(&_M_cond, 0);
+    int __e = __GTHREAD_COND_INIT_FUNCTION(&_M_cond, 0);
 
     if (__e)
       __throw_system_error(__e);
Comment 34 ro@CeBiTec.Uni-Bielefeld.DE 2012-02-03 09:48:15 UTC
> Since a similar problem exists for darwin11's
> PTHREAD_RECURSIVE_MUTEX_INITIALIZER this solution is not OSF-specific.  This
> allows config/os/*/os_defines.h to define one or more of:
>
> _GTHREAD_USE_MUTEX_INIT_FUNC
> _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
> _GTHREAD_USE_COND_INIT_FUNC
>
> which will cause gthr-posix.h to #undef the INIT macro and define an
> INIT_FUNCTION instead.  
>
> Would this work here too?  You could either add a config/os/osf/os_defines.h

I guess so.  I'll try it with this weekend's bootstrap.

> file (which would also need the other files in config/os/generic to be copied
> for osf) or you could just put this in gthr-posix.h
>
> #ifdef __osf__
> # define _GTHREAD_USE_MUTEX_INIT_FUNC
> # define _GTHREAD_USE_COND_INIT_FUNC
> #endif

Since that file already has osf-specific code (and the port will go away
after 4.7 anyway), I'll probably go this route.

Thanks.
	Rainer
Comment 35 ro@CeBiTec.Uni-Bielefeld.DE 2012-02-03 09:50:39 UTC
> --- Comment #33 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-02-03 08:52:17 UTC ---
> Oops, this hunk would be needed too
 
I know, I already had this in my failed attempt to use
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION and __GTHREAD_COND_INIT_FUNCTION
everywhere.

        Rainer
Comment 36 Jonathan Wakely 2012-02-07 09:19:35 UTC
Author: redi
Date: Tue Feb  7 09:19:27 2012
New Revision: 183955

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=183955
Log:
libgcc/

	PR libstdc++/51296
	PR libstdc++/51906
	* gthr-posix.h: Allow static initializer macros to be disabled.
	(__gthrw_pthread_cond_init): Define weak reference unconditionally.

libstdc++-v3/

	PR libstdc++/51296
	* include/std/mutex (__mutex_base::~__mutex_base): Declare noexcept.
	* src/c++11/condition_variable.cc (condition_variable): Use macro for
	initializer function.

	PR libstdc++/51906
	* config/os/bsd/darwin/os_defines.h: Disable static initializer for
	recursive mutexes.

Modified:
    trunk/libgcc/ChangeLog
    trunk/libgcc/gthr-posix.h
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/config/os/bsd/darwin/os_defines.h
    trunk/libstdc++-v3/include/std/mutex
    trunk/libstdc++-v3/src/c++11/condition_variable.cc
Comment 37 Jonathan Wakely 2012-02-07 09:22:29 UTC
Rainer, you should now be able to define _GTHREAD_USE_MUTEX_INIT_FUNC and _GTHREAD_USE_COND_INIT_FUNC (either in gthr-posix.h or os_defines.h or wherever you see fit) and then the tests should pass.
Comment 38 ro@CeBiTec.Uni-Bielefeld.DE 2012-02-10 17:01:39 UTC
> --- Comment #37 from Jonathan Wakely <redi at gcc dot gnu.org> 2012-02-07 09:22:29 UTC ---
> Rainer, you should now be able to define _GTHREAD_USE_MUTEX_INIT_FUNC and
> _GTHREAD_USE_COND_INIT_FUNC (either in gthr-posix.h or os_defines.h or wherever
> you see fit) and then the tests should pass.

I've already posted a patch that does this:

	http://gcc.gnu.org/ml/gcc-patches/2012-02/msg00499.html

	Rainer
Comment 39 Rainer Orth 2012-02-10 18:10:19 UTC
Author: ro
Date: Fri Feb 10 18:10:12 2012
New Revision: 184108

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=184108
Log:
Use __GTHREAD_MUTEX_INIT_FUNCTION on Tru64 UNIX (PR libstdc++/51296)

	PR libstdc++/51296
	* config/os/osf/ctype_base.h,
	config/os/osf/ctype_configure_char.cc,
	config/os/osf/ctype_inline.h, config/os/osf/error_constants.h:
	Copy from config/os/generic.
	* config/os/osf/os_defines.h: Likewise.
	(_GTHREAD_USE_MUTEX_INIT_FUNC, _GTHREAD_USE_COND_INIT_FUNC):
	Define.
	* configure.host <osf*>: Use os/osf for os_include_dir.

Added:
    trunk/libstdc++-v3/config/os/osf/
    trunk/libstdc++-v3/config/os/osf/ctype_base.h
      - copied, changed from r184107, trunk/libstdc++-v3/config/os/generic/ctype_base.h
    trunk/libstdc++-v3/config/os/osf/ctype_configure_char.cc
      - copied, changed from r184107, trunk/libstdc++-v3/config/os/generic/ctype_configure_char.cc
    trunk/libstdc++-v3/config/os/osf/ctype_inline.h
      - copied, changed from r184107, trunk/libstdc++-v3/config/os/generic/ctype_inline.h
    trunk/libstdc++-v3/config/os/osf/error_constants.h
      - copied, changed from r184107, trunk/libstdc++-v3/config/os/generic/error_constants.h
    trunk/libstdc++-v3/config/os/osf/os_defines.h
      - copied, changed from r184107, trunk/libstdc++-v3/config/os/generic/os_defines.h
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/configure.host
Comment 40 Rainer Orth 2012-02-10 18:13:25 UTC
Fixed for 4.7.0.