OSDN Git Service

2008-09-23 Chris Fairles <cfairles@gcc.gnu.org>
authorcfairles <cfairles@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Sep 2008 17:34:29 +0000 (17:34 +0000)
committercfairles <cfairles@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 23 Sep 2008 17:34:29 +0000 (17:34 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140603 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
libstdc++-v3/ChangeLog
libstdc++-v3/config/abi/pre/gnu.ver
libstdc++-v3/include/std/chrono
libstdc++-v3/include/std/condition_variable
libstdc++-v3/src/chrono.cc
libstdc++-v3/src/condition_variable.cc
libstdc++-v3/testsuite/30_threads/condition_variable/cons/assign_neg.cc
libstdc++-v3/testsuite/30_threads/condition_variable/cons/copy_neg.cc
libstdc++-v3/testsuite/30_threads/condition_variable/member/1.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/condition_variable/member/2.cc [new file with mode: 0644]
libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/assign_neg.cc
libstdc++-v3/testsuite/30_threads/condition_variable_any/cons/copy_neg.cc

index bdf354b..92e5267 100644 (file)
@@ -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
index df69c87..56fa9be 100644 (file)
@@ -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;
index d20c7f4..76dc93c 100644 (file)
@@ -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;    
   }
 }
 
index f2035d6..8325ff1 100644 (file)
@@ -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
index 88fb4c1..c44d793 100644 (file)
@@ -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
   }
 }
 
index f1ae33a..cdad051 100644 (file)
@@ -1,4 +1,4 @@
-// mutex -*- C++ -*-
+// condition_variable -*- C++ -*-
 
 // Copyright (C) 2008 Free Software Foundation, Inc.
 //
index 331a814..601bd82 100644 (file)
@@ -41,4 +41,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 40 }
-// { dg-error "deleted function" "" { target *-*-* } 60 }
+// { dg-error "deleted function" "" { target *-*-* } 62 }
index 329279f..b617c8a 100644 (file)
@@ -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 (file)
index 0000000..a4fd9bc
--- /dev/null
@@ -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 (file)
index 0000000..25b3f24
--- /dev/null
@@ -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;
+}
index 7cdd252..7399ed6 100644 (file)
@@ -41,4 +41,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 40 }
-// { dg-error "deleted function" "" { target *-*-* } 168 }
+// { dg-error "deleted function" "" { target *-*-* } 170 }
index d71e955..86c81a2 100644 (file)
@@ -40,4 +40,4 @@ void test01()
 }
 
 // { dg-error "used here" "" { target *-*-* } 39 }
-// { dg-error "deleted function" "" { target *-*-* } 167 }
+// { dg-error "deleted function" "" { target *-*-* } 169 }