Patchwork 3 libstdc++ tests fail at random

login
register
mail settings
Submitter Jonathan Wakely
Date Dec. 8, 2013, 10:18 p.m.
Message ID <CAH6eHdT1HB4wQhF7Dbra-e+5tFWUruPb+t+o7gzLeLLf4dDU9Q@mail.gmail.com>
Download mbox | patch
Permalink /patch/298896/
State New
Headers show

Comments

Jonathan Wakely - Dec. 8, 2013, 10:18 p.m.
On 7 December 2013 17:28, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Sat, Dec 7, 2013 at 9:26 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Sat, Dec 7, 2013 at 9:09 AM, Jakub Jelinek <jakub@redhat.com> wrote:
>>>> >FAIL: 30_threads/async/async.cc execution test
>>>
>>> async.exe: /usr/src/gcc/libstdc++-v3/testsuite/30_threads/async/async.cc:66: void test02(): Assertion `status == std::future_status::ready' failed.
>>>
>>> This one fails pretty frequently for me, 6 times out of last 12 i686-linux
>>
>> Same here.
>>
>>> bootstraps/regtests, starting with ~ Nov 21th bootstrap (but before that
>>
>> It started for me around revision 205144.
>>
>
> http://gcc.gnu.org/ml/gcc-cvs/2013-11/msg00869.html
>
> changed 30_threads/async/async.cc.

My recent change to that test introduced a race, the main thread could
wake up and check for readiness before the shared state had been made
ready.  Fixed by this patch.

Tested x86_64-linux and i686-linux, committed to trunk.

2013-12-08  Jonathan Wakely  <jwakely.gcc@gmail.com>

        * testsuite/30_threads/async/async.cc: Fix race condition in test.
commit 2141b30307e7802625e72eba3037c0528fcaa76d
Author: Jonathan Wakely <jwakely.gcc@gmail.com>
Date:   Sun Dec 8 21:35:22 2013 +0000

    	* testsuite/30_threads/async/async.cc: Fix race condition in test.

Patch

diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc
index 1f94494..05fd23c 100644
--- a/libstdc++-v3/testsuite/30_threads/async/async.cc
+++ b/libstdc++-v3/testsuite/30_threads/async/async.cc
@@ -29,23 +29,18 @@ 
 
 using namespace std;
 
-struct work {
-  typedef void result_type;
-  void operator()(mutex& m, condition_variable& cv)
-  {
-    unique_lock<mutex> l(m);
-    cv.notify_one();
-  }
-};
+void work(mutex& m)
+{
+  unique_lock<mutex> l(m);
+}
 
 void test01()
 {
   mutex m;
-  condition_variable cv;
   unique_lock<mutex> l(m);
-  future<void> f1 = async(launch::async, work(), ref(m), ref(cv));
-  cv.wait(l);
-  f1.get();
+  future<void> f1 = async(launch::async, &work, ref(m));
+  l.unlock();  // allow async thread to proceed
+  f1.get();    // wait for it to finish
 }
 
 void test02()
@@ -53,15 +48,15 @@  void test02()
   bool test __attribute__((unused)) = true;
 
   mutex m;
-  condition_variable cv;
   unique_lock<mutex> l(m);
-  future<void> f1 = async(launch::async, work(), ref(m), ref(cv));
+  future<void> f1 = async(launch::async, &work, ref(m));
   std::future_status status;
   status = f1.wait_for(std::chrono::milliseconds(1));
   VERIFY( status == std::future_status::timeout );
   status = f1.wait_until(std::chrono::system_clock::now());
   VERIFY( status == std::future_status::timeout );
-  cv.wait(l);
+  l.unlock();  // allow async thread to proceed
+  f1.wait();   // wait for it to finish
   status = f1.wait_for(std::chrono::milliseconds(0));
   VERIFY( status == std::future_status::ready );
   status = f1.wait_until(std::chrono::system_clock::now());