aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorChris Fairles <cfairles@gcc.gnu.org>2008-09-23 17:34:29 +0000
committerChris Fairles <cfairles@gcc.gnu.org>2008-09-23 17:34:29 +0000
commit8839907955ae3ad3240fc48dd082f5758e8dfa41 (patch)
tree35b70f711f4bbfa92cadbd4c246de21481316e41 /libstdc++-v3
parent1304d5813db7e623b4e64757bf95dc919d36c891 (diff)
downloadgcc-8839907955ae3ad3240fc48dd082f5758e8dfa41.zip
gcc-8839907955ae3ad3240fc48dd082f5758e8dfa41.tar.gz
gcc-8839907955ae3ad3240fc48dd082f5758e8dfa41.tar.bz2
chrono: If _GLIBCXX_USE_MONOTONIC_CLOCK is defined...
2008-09-23 Chris Fairles <cfairles@gcc.gnu.org> * include/std/chrono: If _GLIBCXX_USE_MONOTONIC_CLOCK is defined, don't typedef monotonic_clock to system_clock and instead declare new class. * src/chrono.cc: Conditionally define monotonic_clock::now(). * include/std/condition_variable (wait_until): Throw exception if __gthread_cond_timedwait returns with error other than timed_out. Use system_clock as known clock type (__clock_t) and add overloads for known and unknown clocks. In the unknown case, sync to the known clock. Implement overload taking a predicate. (wait_for): Implement overload taking a predicate. * config/abi/pre/gnu.ver: Add exports for monotonic_clock. * testsuite/30_threads/condition_variable_any/cons/assign_neg.cc: Modify line numbers. * testsuite/30_threads/condition_variable_any/cons/copy_neg.cc: Likewise. * testsuite/30_threads/condition_variable/cons/assign_neg.cc: Likewise. * testsuite/30_threads/condition_variable/cons/copy_neg.cc: Likewise. * testsuite/30_threads/condition_variable/member/1.cc: New. * testsuite/30_threads/condition_variable/member/2.cc: Likewise. From-SVN: r140603
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog21
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver2
-rw-r--r--libstdc++-v3/include/std/chrono25
-rw-r--r--libstdc++-v3/include/std/condition_variable92
-rw-r--r--libstdc++-v3/src/chrono.cc46
-rw-r--r--libstdc++-v3/src/condition_variable.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/condition_variable/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/condition_variable/cons/copy_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/condition_variable/member/1.cc67
-rw-r--r--libstdc++-v3/testsuite/30_threads/condition_variable/member/2.cc67
-rw-r--r--libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/assign_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/copy_neg.cc2
12 files changed, 254 insertions, 76 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index bdf354b..92e5267 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,24 @@
+2008-09-23 Chris Fairles <cfairles@gcc.gnu.org>
+
+ * include/std/chrono: If _GLIBCXX_USE_MONOTONIC_CLOCK is defined, don't
+ typedef monotonic_clock to system_clock and instead declare new class.
+ * src/chrono.cc: Conditionally define monotonic_clock::now().
+ * include/std/condition_variable (wait_until): Throw exception if
+ __gthread_cond_timedwait returns with error other than timed_out. Use
+ system_clock as known clock type (__clock_t) and add overloads for known
+ and unknown clocks. In the unknown case, sync to the known clock.
+ Implement overload taking a predicate.
+ (wait_for): Implement overload taking a predicate.
+ * config/abi/pre/gnu.ver: Add exports for monotonic_clock.
+ * testsuite/30_threads/condition_variable_any/cons/assign_neg.cc: Modify
+ line numbers.
+ * testsuite/30_threads/condition_variable_any/cons/copy_neg.cc:
+ Likewise.
+ * testsuite/30_threads/condition_variable/cons/assign_neg.cc: Likewise.
+ * testsuite/30_threads/condition_variable/cons/copy_neg.cc: Likewise.
+ * testsuite/30_threads/condition_variable/member/1.cc: New.
+ * testsuite/30_threads/condition_variable/member/2.cc: Likewise.
+
2008-09-23 Paolo Carlini <paolo.carlini@oracle.com>
PR libstdc++/37624
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index df69c87..56fa9be 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -952,6 +952,8 @@ GLIBCXX_3.4.11 {
# chrono
_ZNSt6chrono12system_clock12is_monotonicE;
_ZNSt6chrono12system_clock3nowEv;
+ _ZNSt6chrono15monotonic_clock12is_monotonicE;
+ _ZNSt6chrono15monotonic_clock3nowEv;
# string/wstring initializer_list overloads
_ZNSs6appendESt16initializer_listIcE;
diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono
index d20c7f4..76dc93c 100644
--- a/libstdc++-v3/include/std/chrono
+++ b/libstdc++-v3/include/std/chrono
@@ -578,8 +578,7 @@ namespace std
/// system_clock
struct system_clock
{
-#if defined(_GLIBCXX_USE_CLOCK_MONOTONIC) || \
- defined(_GLIBCXX_USE_CLOCK_REALTIME)
+#ifdef _GLIBCXX_USE_CLOCK_REALTIME
typedef chrono::nanoseconds duration;
#elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
typedef chrono::microseconds duration;
@@ -591,11 +590,7 @@ namespace std
typedef duration::period period;
typedef chrono::time_point<system_clock, duration> time_point;
-#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
- static const bool is_monotonic = true;
-#else
static const bool is_monotonic = false;
-#endif
static time_point
now();
@@ -625,8 +620,24 @@ namespace std
*/
};
+#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
+ struct monotonic_clock
+ {
+ typedef chrono::nanoseconds duration;
+ typedef duration::rep rep;
+ typedef duration::period period;
+ typedef chrono::time_point<monotonic_clock, duration> time_point;
+
+ static const bool is_monotonic = true;
+
+ static time_point
+ now();
+ };
+#else
+ typedef system_clock monotonic_clock;
+#endif
+
typedef system_clock high_resolution_clock;
- typedef system_clock monotonic_clock;
}
}
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable
index f2035d6..8325ff1 100644
--- a/libstdc++-v3/include/std/condition_variable
+++ b/libstdc++-v3/include/std/condition_variable
@@ -50,6 +50,8 @@ namespace std
/// condition_variable
class condition_variable
{
+ typedef chrono::system_clock __clock_t;
+
public:
typedef __gthread_cond_t* native_handle_type;
@@ -76,44 +78,51 @@ namespace std
wait(__lock);
}
- template<typename _Clock, typename _Duration>
+ template<typename _Duration>
bool
- wait_until(unique_lock<mutex>& __lock,
+ wait_until(unique_lock<mutex>& __lock,
+ const chrono::time_point<__clock_t, _Duration>& __atime)
+ { return __wait_until_impl(__lock, __atime); }
+
+ template<typename _Clock, typename _Duration>
+ bool
+ wait_until(unique_lock<mutex>& __lock,
const chrono::time_point<_Clock, _Duration>& __atime)
{
- chrono::time_point<_Clock, chrono::seconds> __s =
- chrono::time_point_cast<chrono::seconds>(__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;
- chrono::nanoseconds __ns =
- chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
-
- __gthread_time_t __ts = {
- static_cast<std::time_t>(__s.time_since_epoch().count()),
- static_cast<long>(__ns.count())
- };
-
- __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(), &__ts);
-
- return __clock_t::now() < __atime;
+ return __wait_until_impl(__lock, __s_atime);
}
template<typename _Clock, typename _Duration, typename _Predicate>
bool
wait_until(unique_lock<mutex>& __lock,
const chrono::time_point<_Clock, _Duration>& __atime,
- _Predicate __p);
+ _Predicate __p)
+ {
+ while(!__p())
+ if(!wait_until(__lock, __atime))
+ return __p();
+
+ return true;
+ }
template<typename _Rep, typename _Period>
bool
wait_for(unique_lock<mutex>& __lock,
const chrono::duration<_Rep, _Period>& __rtime)
- { return __wait_for_impl(__rtime); }
+ { return wait_until(__lock, __clock_t::now() + __rtime); }
template<typename _Rep, typename _Period, typename _Predicate>
bool
wait_for(unique_lock<mutex>& __lock,
const chrono::duration<_Rep, _Period>& __rtime,
- _Predicate __p);
+ _Predicate __p)
+ { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); }
native_handle_type
native_handle()
@@ -123,35 +132,28 @@ namespace std
__gthread_cond_t _M_cond;
mutex _M_internal_mutex;
-#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
- typedef chrono::monotonic_clock __clock_t;
-#else
- typedef chrono::high_resolution_clock __clock_t;
-#endif
-
- template<typename _Rep, typename _Period>
- typename enable_if<
- ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
- __wait_for_impl(unique_lock<mutex>& __lock,
- const chrono::duration<_Rep, _Period>& __rtime)
- {
- __clock_t::time_point __atime = __clock_t::now()
- + chrono::duration_cast<__clock_t::duration>(__rtime);
+ template<typename _Clock, typename _Duration>
+ bool
+ __wait_until_impl(unique_lock<mutex>& __lock,
+ const chrono::time_point<_Clock, _Duration>& __atime)
+ {
+ chrono::time_point<__clock_t, chrono::seconds> __s =
+ chrono::time_point_cast<chrono::seconds>(__atime);
- return wait_until(__lock, __atime);
- }
-
- template<typename _Rep, typename _Period>
- typename enable_if<
- !ratio_less_equal<__clock_t::period, _Period>::value, bool>::type
- __wait_for_impl(unique_lock<mutex>& __lock,
- const chrono::duration<_Rep, _Period>& __rtime)
- {
- __clock_t::time_point __atime = __clock_t::now()
- + ++chrono::duration_cast<__clock_t::duration>(__rtime);
+ chrono::nanoseconds __ns =
+ chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+
+ __gthread_time_t __ts =
+ {
+ static_cast<std::time_t>(__s.time_since_epoch().count()),
+ static_cast<long>(__ns.count())
+ };
- return wait_until(__lock, __atime);
- }
+ __gthread_cond_timedwait(&_M_cond, __lock.mutex()->native_handle(),
+ &__ts);
+
+ return _Clock::now() < __atime;
+ }
};
/// condition_variable_any
diff --git a/libstdc++-v3/src/chrono.cc b/libstdc++-v3/src/chrono.cc
index 88fb4c1..c44d793 100644
--- a/libstdc++-v3/src/chrono.cc
+++ b/libstdc++-v3/src/chrono.cc
@@ -47,29 +47,37 @@ namespace std
system_clock::time_point
system_clock::now()
{
-#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
- timespec tp;
- // -EINVAL, -EFAULT
- clock_gettime(CLOCK_MONOTONIC, &tp);
- return time_point(duration(chrono::seconds(tp.tv_sec)
- + chrono::nanoseconds(tp.tv_nsec)));
-#elif defined(_GLIBCXX_USE_CLOCK_REALTIME)
- timespec tp;
- // -EINVAL, -EFAULT
- clock_gettime(CLOCK_REALTIME, &tp);
- return time_point(duration(chrono::seconds(tp.tv_sec)
- + chrono::nanoseconds(tp.tv_nsec)));
+#ifdef _GLIBCXX_USE_CLOCK_REALTIME
+ timespec tp;
+ // -EINVAL, -EFAULT
+ clock_gettime(CLOCK_REALTIME, &tp);
+ return time_point(duration(chrono::seconds(tp.tv_sec)
+ + chrono::nanoseconds(tp.tv_nsec)));
#elif defined(_GLIBCXX_USE_GETTIMEOFDAY)
- timeval tv;
- // EINVAL, EFAULT
- gettimeofday(&tv, NULL);
- return time_point(duration(chrono::seconds(tv.tv_sec)
- + chrono::microseconds(tv.tv_usec)));
+ timeval tv;
+ // EINVAL, EFAULT
+ gettimeofday(&tv, NULL);
+ return time_point(duration(chrono::seconds(tv.tv_sec)
+ + chrono::microseconds(tv.tv_usec)));
#else
- std::time_t __sec = std::time(0);
- return system_clock::from_time_t(__sec);
+ std::time_t __sec = std::time(0);
+ return system_clock::from_time_t(__sec);
#endif
}
+
+#ifdef _GLIBCXX_USE_CLOCK_MONOTONIC
+ const bool monotonic_clock::is_monotonic;
+
+ monotonic_clock::time_point
+ monotonic_clock::now()
+ {
+ timespec tp;
+ // -EINVAL, -EFAULT
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ return time_point(duration(chrono::seconds(tp.tv_sec)
+ + chrono::nanoseconds(tp.tv_nsec)));
+ }
+#endif
}
}
diff --git a/libstdc++-v3/src/condition_variable.cc b/libstdc++-v3/src/condition_variable.cc
index f1ae33a..cdad051 100644
--- a/libstdc++-v3/src/condition_variable.cc
+++ b/libstdc++-v3/src/condition_variable.cc
@@ -1,4 +1,4 @@
-// mutex -*- C++ -*-
+// condition_variable -*- C++ -*-
// Copyright (C) 2008 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/cons/assign_neg.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/cons/assign_neg.cc
index 331a814..601bd82 100644
--- a/libstdc++-v3/testsuite/30_threads/condition_variable/cons/assign_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable/cons/assign_neg.cc
@@ -41,4 +41,4 @@ void test01()
}
// { dg-error "used here" "" { target *-*-* } 40 }
-// { dg-error "deleted function" "" { target *-*-* } 60 }
+// { dg-error "deleted function" "" { target *-*-* } 62 }
diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/cons/copy_neg.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/cons/copy_neg.cc
index 329279f..b617c8a 100644
--- a/libstdc++-v3/testsuite/30_threads/condition_variable/cons/copy_neg.cc
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable/cons/copy_neg.cc
@@ -40,4 +40,4 @@ void test01()
}
// { dg-error "used here" "" { target *-*-* } 39 }
-// { dg-error "deleted function" "" { target *-*-* } 59 }
+// { dg-error "deleted function" "" { target *-*-* } 61 }
diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/member/1.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/member/1.cc
new file mode 100644
index 0000000..a4fd9bc
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable/member/1.cc
@@ -0,0 +1,67 @@
+// { 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 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <chrono>
+#include <condition_variable>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ try
+ {
+ std::chrono::microseconds ms(500);
+ std::condition_variable c1;
+ std::mutex m;
+ std::unique_lock<std::mutex> l(m);
+
+ auto then = std::chrono::system_clock::now();
+ bool result = c1.wait_for(l, ms);
+ VERIFY( !result );
+ VERIFY( (std::chrono::system_clock::now() - then) >= ms );
+ VERIFY( l.owns_lock() );
+ }
+ catch (const std::system_error& e)
+ {
+ VERIFY( false );
+ }
+ catch (...)
+ {
+ VERIFY( false );
+ }
+
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/condition_variable/member/2.cc b/libstdc++-v3/testsuite/30_threads/condition_variable/member/2.cc
new file mode 100644
index 0000000..25b3f24
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/condition_variable/member/2.cc
@@ -0,0 +1,67 @@
+// { 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 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 2, 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 COPYING. If not, write to the Free
+// Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <chrono>
+#include <condition_variable>
+#include <system_error>
+#include <testsuite_hooks.h>
+
+int main()
+{
+ bool test __attribute__((unused)) = true;
+
+ try
+ {
+ std::chrono::microseconds ms(500);
+ std::condition_variable c1;
+ std::mutex m;
+ std::unique_lock<std::mutex> l(m);
+
+ auto then = std::chrono::monotonic_clock::now();
+ bool result = c1.wait_until(l, then + ms);
+ VERIFY( !result );
+ VERIFY( (std::chrono::monotonic_clock::now() - then) >= ms );
+ VERIFY( l.owns_lock() );
+ }
+ catch (const std::system_error& e)
+ {
+ VERIFY( false );
+ }
+ catch (...)
+ {
+ VERIFY( false );
+ }
+
+ 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 7cdd252..7399ed6 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
@@ -41,4 +41,4 @@ void test01()
}
// { dg-error "used here" "" { target *-*-* } 40 }
-// { dg-error "deleted function" "" { target *-*-* } 168 }
+// { dg-error "deleted function" "" { target *-*-* } 170 }
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 d71e955..86c81a2 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
@@ -40,4 +40,4 @@ void test01()
}
// { dg-error "used here" "" { target *-*-* } 39 }
-// { dg-error "deleted function" "" { target *-*-* } 167 }
+// { dg-error "deleted function" "" { target *-*-* } 169 }