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
This commit is contained in:
parent
1304d5813d
commit
8839907955
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
*/
|
||||
};
|
||||
|
||||
typedef system_clock high_resolution_clock;
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 _Duration>
|
||||
bool
|
||||
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,34 +132,27 @@ 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)
|
||||
template<typename _Clock, typename _Duration>
|
||||
bool
|
||||
__wait_until_impl(unique_lock<mutex>& __lock,
|
||||
const chrono::time_point<_Clock, _Duration>& __atime)
|
||||
{
|
||||
__clock_t::time_point __atime = __clock_t::now()
|
||||
+ chrono::duration_cast<__clock_t::duration>(__rtime);
|
||||
chrono::time_point<__clock_t, chrono::seconds> __s =
|
||||
chrono::time_point_cast<chrono::seconds>(__atime);
|
||||
|
||||
return wait_until(__lock, __atime);
|
||||
}
|
||||
chrono::nanoseconds __ns =
|
||||
chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
|
||||
|
||||
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)
|
||||
__gthread_time_t __ts =
|
||||
{
|
||||
__clock_t::time_point __atime = __clock_t::now()
|
||||
+ ++chrono::duration_cast<__clock_t::duration>(__rtime);
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -47,13 +47,7 @@ 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)
|
||||
#ifdef _GLIBCXX_USE_CLOCK_REALTIME
|
||||
timespec tp;
|
||||
// -EINVAL, -EFAULT
|
||||
clock_gettime(CLOCK_REALTIME, &tp);
|
||||
@ -70,6 +64,20 @@ namespace std
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// mutex -*- C++ -*-
|
||||
// condition_variable -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2008 Free Software Foundation, Inc.
|
||||
//
|
||||
|
@ -41,4 +41,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 40 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 60 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 62 }
|
||||
|
@ -40,4 +40,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 39 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 59 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 61 }
|
||||
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -41,4 +41,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 40 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 168 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 170 }
|
||||
|
@ -40,4 +40,4 @@ void test01()
|
||||
}
|
||||
|
||||
// { dg-error "used here" "" { target *-*-* } 39 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 167 }
|
||||
// { dg-error "deleted function" "" { target *-*-* } 169 }
|
||||
|
Loading…
Reference in New Issue
Block a user