diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a3c413b6555..a9e17bc87f9 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,21 @@ +2010-02-03 Jonathan Wakely + + * include/std/condition_variable (condition_variable_any): Provide + definitions for all members. + * src/condition_variable.cc (condition_variable_any): Adjust + definitions. + * config/abi/pre/gnu.ver: Adjust exports for condition_variable_any. + * testsuite/30_threads/condition_variable_any/cons/assign_neg.cc: + Adjust dg-error line number. + * testsuite/30_threads/condition_variable_any/cons/copy_neg.cc: + Likewise. + * testsuite/30_threads/condition_variable_any/members/1.cc: New. + * testsuite/30_threads/condition_variable_any/members/2.cc: New. + * testsuite/30_threads/condition_variable_any/requirements/ + standard_layout.cc: Remove. + * testsuite/30_threads/condition_variable_any/native_handle/ + typesizes.cc: Remove. + 2010-02-02 Paolo Carlini * include/ext/vstring.h (__versa_string::shrink_to_fit): Fix diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver index 4b5f6d0d246..447b63ede49 100644 --- a/libstdc++-v3/config/abi/pre/gnu.ver +++ b/libstdc++-v3/config/abi/pre/gnu.ver @@ -1113,10 +1113,6 @@ GLIBCXX_3.4.14 { # std::time_get::_M_extract_wday_or_month _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE24_M_extract_wday_or_month*; - # condition_variable_any::notify_* - _ZNSt22condition_variable_any10notify_allEv; - _ZNSt22condition_variable_any10notify_oneEv; - } GLIBCXX_3.4.13; # Symbols in the support library (libsupc++) have their own tag. diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable index d59fdd4e9a7..ff5af7214ca 100644 --- a/libstdc++-v3/include/std/condition_variable +++ b/libstdc++-v3/include/std/condition_variable @@ -162,14 +162,15 @@ namespace std }; /// condition_variable_any - // Like above, only mutex may not have try_lock. + // Like above, but mutex is not required to have try_lock. class condition_variable_any { - typedef __gthread_cond_t __native_type; - __native_type _M_cond; + typedef chrono::system_clock __clock_t; + condition_variable _M_cond; + mutex _M_mutex; public: - typedef __native_type* native_handle_type; + typedef condition_variable::native_handle_type native_handle_type; condition_variable_any() throw (); ~condition_variable_any() throw (); @@ -178,14 +179,29 @@ namespace std condition_variable_any& operator=(const condition_variable_any&) = delete; void - notify_one(); + notify_one() + { + lock_guard __lock(_M_mutex); + _M_cond.notify_one(); + } void - notify_all(); + notify_all() + { + lock_guard __lock(_M_mutex); + _M_cond.notify_all(); + } template void - wait(_Lock& __lock); + wait(_Lock& __lock) + { + unique_lock __my_lock(_M_mutex); + __lock.unlock(); + _M_cond.wait(__my_lock); + __lock.lock(); + } + template void @@ -198,7 +214,14 @@ namespace std template cv_status wait_until(_Lock& __lock, - const chrono::time_point<_Clock, _Duration>& __atime); + const chrono::time_point<_Clock, _Duration>& __atime) + { + unique_lock __my_lock(_M_mutex); + __lock.unlock(); + cv_status __status = _M_cond.wait_until(__my_lock, __atime); + __lock.lock(); + return __status; + } template @@ -215,17 +238,19 @@ namespace std template cv_status - wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime); + wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime) + { return wait_until(__lock, __clock_t::now() + __rtime); } template bool wait_for(_Lock& __lock, - const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p); + const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) + { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); } native_handle_type native_handle() - { return &_M_cond; } + { return _M_cond.native_handle(); } }; // @} group condition_variables diff --git a/libstdc++-v3/src/condition_variable.cc b/libstdc++-v3/src/condition_variable.cc index b4203799253..fdcb6a04b38 100644 --- a/libstdc++-v3/src/condition_variable.cc +++ b/libstdc++-v3/src/condition_variable.cc @@ -80,44 +80,10 @@ namespace std } condition_variable_any::condition_variable_any() throw () - { -#ifdef __GTHREAD_COND_INIT - __native_type __tmp = __GTHREAD_COND_INIT; - _M_cond = __tmp; -#else - int __e = __gthread_cond_init(&_M_cond, NULL); - - if (__e) - __throw_system_error(__e); -#endif - } + { } condition_variable_any::~condition_variable_any() throw () - { - __gthread_cond_destroy(&_M_cond); - } - - void - condition_variable_any::notify_one() - { - int __e = __gthread_cond_signal(&_M_cond); - - // XXX not in spec - // EINVAL - if (__e) - __throw_system_error(__e); - } - - void - condition_variable_any::notify_all() - { - int __e = __gthread_cond_broadcast(&_M_cond); - - // XXX not in spec - // EINVAL - if (__e) - __throw_system_error(__e); - } + { } } #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1 diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/assign_neg.cc index 5e3e30231b4..8fa79a2cf1a 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/assign_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/assign_neg.cc @@ -32,4 +32,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 31 } -// { dg-error "deleted function" "" { target *-*-* } 178 } +// { dg-error "deleted function" "" { target *-*-* } 179 } diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/copy_neg.cc index 2b61c1b9621..344f90c961c 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/copy_neg.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/copy_neg.cc @@ -31,4 +31,4 @@ void test01() } // { dg-error "used here" "" { target *-*-* } 30 } -// { dg-error "deleted function" "" { target *-*-* } 177 } +// { dg-error "deleted function" "" { target *-*-* } 178 } diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable_any/native_handle/typesizes.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/1.cc similarity index 55% rename from libstdc++-v3/testsuite/30_threads/condition_variable_any/native_handle/typesizes.cc rename to libstdc++-v3/testsuite/30_threads/condition_variable_any/members/1.cc index ae2163d9cb9..07743928a26 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable_any/native_handle/typesizes.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/1.cc @@ -5,7 +5,7 @@ // { dg-require-cstdint "" } // { dg-require-gthreads "" } -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2010 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -22,12 +22,64 @@ // with this library; see the file COPYING3. If not see // . +#include #include -#include +#include +#include + +struct Mutex +{ + Mutex() : locked(false) { } + + void lock() + { + if (locked) + throw locked; + mtx.lock(); + locked = true; + } + + void unlock() + { + if (!locked) + throw locked; + mtx.unlock(); + locked = false; + } + + std::mutex mtx; + bool locked; +}; + +void test01() +{ + bool test __attribute__((unused)) = true; + + try + { + std::chrono::microseconds ms(500); + std::condition_variable_any c1; + Mutex m; + m.lock(); + + auto then = std::chrono::system_clock::now(); + std::cv_status result = c1.wait_for(m, ms); + VERIFY( result == std::cv_status::timeout ); + VERIFY( (std::chrono::system_clock::now() - then) >= ms ); + VERIFY( m.locked ); + } + catch (const std::system_error& e) + { + VERIFY( false ); + } + catch (...) + { + VERIFY( false ); + } +} int main() { - typedef std::condition_variable_any test_type; - __gnu_test::compare_type_to_native_type(); + test01(); return 0; } diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc new file mode 100644 index 00000000000..8e58dce818b --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc @@ -0,0 +1,86 @@ +// { dg-do run { target *-*-freebsd* *-*-netbsd* *-*-linux* *-*-solaris* *-*-cygwin *-*-darwin* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthread" { target *-*-freebsd* *-*-netbsd* *-*-linux* alpha*-*-osf* mips-sgi-irix6* } } +// { dg-options " -std=gnu++0x -pthreads" { target *-*-solaris* } } +// { dg-options " -std=gnu++0x " { target *-*-cygwin *-*-darwin* } } +// { dg-require-cstdint "" } +// { dg-require-gthreads "" } + +// Copyright (C) 2010 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include +#include + +struct Mutex +{ + Mutex() : locked(false) { } + + void lock() + { + if (locked) + throw locked; + mtx.lock(); + locked = true; + } + + void unlock() + { + if (!locked) + throw locked; + mtx.unlock(); + locked = false; + } + + std::mutex mtx; + bool locked; +}; + + +void test01() +{ + bool test __attribute__((unused)) = true; + + try + { + std::chrono::microseconds ms(500); + std::condition_variable_any c1; + Mutex m; + m.lock(); + + auto then = std::chrono::monotonic_clock::now(); + std::cv_status result = c1.wait_until(m, then + ms); + VERIFY( result == std::cv_status::timeout ); + VERIFY( (std::chrono::monotonic_clock::now() - then) >= ms ); + VERIFY( m.locked ); + } + catch (const std::system_error& e) + { + VERIFY( false ); + } + catch (...) + { + VERIFY( false ); + } +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable_any/requirements/standard_layout.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/requirements/standard_layout.cc deleted file mode 100644 index 74e57ab354a..00000000000 --- a/libstdc++-v3/testsuite/30_threads/condition_variable_any/requirements/standard_layout.cc +++ /dev/null @@ -1,30 +0,0 @@ -// { dg-do compile } -// { dg-options "-std=gnu++0x" } -// { dg-require-cstdint "" } -// { dg-require-gthreads "" } - -// Copyright (C) 2010 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING3. If not see -// . - -#include -#include - -void test01() -{ - __gnu_test::standard_layout test; - test.operator()(); -}