Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spurious wakeups on condition_variable with g++ and clang++

Take the following code:

#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>

using namespace std;

int main() {
  mutex m;
  condition_variable c;

  bool fired = false;
  int i = 0;

  // This thread counts the times the condition_variable woke up.
  // If no spurious wakeups occur it should be close to 5.
  thread t([&]() {
    unique_lock<mutex> l(m);
    while (!fired) {
      c.wait_for(l, chrono::milliseconds(100));
      ++i;
    }
  });

  // Here we wait for 500ms, then signal the other thread to stop
  this_thread::sleep_for(chrono::milliseconds(500));
  {
    unique_lock<mutex> l(m);
    fired = true;
    c.notify_all();
    cout << i << endl;
  }
  t.join();
}

Now, when I build this using clang++ -std=c++11 -pthread foo.cpp everything is fine, it outputs 4 on my machine. When I build it with g++ -std=c++11 -pthread foo.cpp however I get something very large every time, e.g. 81513. I realize the number of spurious wakeups is undefined, but I was surprised to see it so high.

Additional information: When I replace the wait_for by a simple wait both clang and g++ output 0.

Is this a bug / feature in g++? Why is it even different from clang? Can I get it to behave more reasonably?

Also: gcc version 4.7.3 (Debian 4.7.3-4).

like image 219
lucas clemente Avatar asked Nov 11 '22 22:11

lucas clemente


1 Answers

I managed to get g++-4.8 running, and the problem is gone. Very weird, seems like a bug in g++-4.7.3, although I wasn't able to reproduce it on another machine.

like image 101
lucas clemente Avatar answered Nov 15 '22 06:11

lucas clemente