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
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
(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?
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 #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 #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 #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
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.
(In reply to comment #7) > __GTHREAD_MUTEX_INIT > __GTHREAD_MUTEX_INIT sorry, ignore the double-paste ;)
> --- 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
ah so the scan-assembler test is finding the stabs info, not actually a call to the constructor
> --- 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
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
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 #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
(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.
> 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
(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
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 #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
(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 #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
(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.
> 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
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
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 #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
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.
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
(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 #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
(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
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
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);
> 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 #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
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
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 #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
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
Fixed for 4.7.0.