From 023cee968b768ec0dfcbd35373d6195332d5dd76 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 29 Jan 2010 22:46:31 +0000 Subject: [PATCH] condition_variable (condition_variable_any:: __wait_until_impl): Add. 2010-01-29 Paolo Carlini * include/std/condition_variable (condition_variable_any:: __wait_until_impl): Add. (condition_variable_any::wait_until): Provide definitions. * testsuite/30_threads/condition_variable_any/members/2.cc: New. * 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/members/1.cc: Minor stylistic changes. * testsuite/30_threads/condition_variable/members/1.cc: Likewise. From-SVN: r156367 --- libstdc++-v3/ChangeLog | 15 +++++ libstdc++-v3/include/std/condition_variable | 51 ++++++++++++++-- .../condition_variable/members/1.cc | 9 ++- .../condition_variable/members/2.cc | 9 ++- .../condition_variable_any/cons/assign_neg.cc | 2 +- .../condition_variable_any/cons/copy_neg.cc | 2 +- .../condition_variable_any/members/2.cc | 61 +++++++++++++++++++ 7 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 33d77900808..5dddc099294 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2010-01-29 Paolo Carlini + + * include/std/condition_variable (condition_variable_any:: + __wait_until_impl): Add. + (condition_variable_any::wait_until): Provide definitions. + * testsuite/30_threads/condition_variable_any/members/2.cc: New. + * 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/members/1.cc: Minor + stylistic changes. + * testsuite/30_threads/condition_variable/members/1.cc: Likewise. + 2010-01-29 Paolo Carlini * include/std/condition_variable (enum class cv_status): Add and diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable index ea4570ee9a3..329b9722d04 100644 --- a/libstdc++-v3/include/std/condition_variable +++ b/libstdc++-v3/include/std/condition_variable @@ -98,10 +98,10 @@ namespace std const chrono::time_point<_Clock, _Duration>& __atime) { // DR 887 - Sync unknown clock to known clock. - typename _Clock::time_point __c_entry = _Clock::now(); - __clock_t::time_point __s_entry = __clock_t::now(); - chrono::nanoseconds __delta = __atime - __c_entry; - __clock_t::time_point __s_atime = __s_entry + __delta; + const typename _Clock::time_point __c_entry = _Clock::now(); + const __clock_t::time_point __s_entry = __clock_t::now(); + const chrono::nanoseconds __delta = __atime - __c_entry; + const __clock_t::time_point __s_atime = __s_entry + __delta; return __wait_until_impl(__lock, __s_atime); } @@ -165,6 +165,7 @@ namespace std // Like above, only mutex may not have try_lock. class condition_variable_any { + typedef chrono::system_clock __clock_t; typedef __gthread_cond_t __native_type; __native_type _M_cond; @@ -201,10 +202,25 @@ namespace std wait(__lock); } + template + cv_status + wait_until(_Lock& __lock, + const chrono::time_point<__clock_t, _Duration>& __atime) + { return __wait_until_impl(__lock, __atime); } + template cv_status wait_until(_Lock& __lock, - const chrono::time_point<_Clock, _Duration>& __atime); + const chrono::time_point<_Clock, _Duration>& __atime) + { + // DR 887 - Sync unknown clock to known clock. + const typename _Clock::time_point __c_entry = _Clock::now(); + const __clock_t::time_point __s_entry = __clock_t::now(); + const chrono::nanoseconds __delta = __atime - __c_entry; + const __clock_t::time_point __s_atime = __s_entry + __delta; + + return __wait_until_impl(__lock, __s_atime); + } template @@ -232,6 +248,31 @@ namespace std native_handle_type native_handle() { return &_M_cond; } + + private: + template + cv_status + __wait_until_impl(_Lock& __lock, + const chrono::time_point<_Clock, _Duration>& __atime) + { + chrono::time_point<__clock_t, chrono::seconds> __s = + chrono::time_point_cast(__atime); + + chrono::nanoseconds __ns = + chrono::duration_cast(__atime - __s); + + __gthread_time_t __ts = + { + static_cast(__s.time_since_epoch().count()), + static_cast(__ns.count()) + }; + + __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(), + &__ts); + + return (_Clock::now() < __atime + ? cv_status::no_timeout : cv_status::timeout); + } }; // @} group condition_variables diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/members/1.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/1.cc index 127960a625d..3b94c236f51 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable/members/1.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/1.cc @@ -5,7 +5,7 @@ // { dg-require-cstdint "" } // { dg-require-gthreads "" } -// Copyright (C) 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009, 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,13 +22,12 @@ // with this library; see the file COPYING3. If not see // . - #include #include #include #include -int main() +void test01() { bool test __attribute__((unused)) = true; @@ -53,6 +52,10 @@ int main() { VERIFY( false ); } +} +int main() +{ + test01(); return 0; } diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc index ab2e8776b84..f4904ada547 100644 --- a/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/2.cc @@ -5,7 +5,7 @@ // { dg-require-cstdint "" } // { dg-require-gthreads "" } -// Copyright (C) 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2008, 2009, 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,13 +22,12 @@ // with this library; see the file COPYING3. If not see // . - #include #include #include #include -int main() +void test01() { bool test __attribute__((unused)) = true; @@ -53,6 +52,10 @@ int main() { VERIFY( false ); } +} +int main() +{ + test01(); return 0; } 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/members/2.cc b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc new file mode 100644 index 00000000000..2cb21ed49c7 --- /dev/null +++ b/libstdc++-v3/testsuite/30_threads/condition_variable_any/members/2.cc @@ -0,0 +1,61 @@ +// { 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) 2008, 2009, 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 + +void test01() +{ + bool test __attribute__((unused)) = true; + + try + { + std::chrono::microseconds ms(500); + std::condition_variable_any c1; + std::mutex m; + std::unique_lock l(m); + + auto then = std::chrono::monotonic_clock::now(); + std::cv_status result = c1.wait_until(l, then + ms); + VERIFY( result == std::cv_status::timeout ); + VERIFY( (std::chrono::monotonic_clock::now() - then) >= ms ); + VERIFY( l.owns_lock() ); + } + catch (const std::system_error& e) + { + VERIFY( false ); + } + catch (...) + { + VERIFY( false ); + } +} + +int main() +{ + test01(); + return 0; +}