[PATCH] [lld][Core] Fix latch synchronization bug.

Rui Ueyama ruiu at google.com
Tue May 7 15:07:46 PDT 2013


Hi Bigcheese,

I think we need to acquire a lock before signal
a condition. Otherwise threads waiting on a condition
variable can miss a signal.

Consider two threads: Thread A executing dec() and thread
B executing sync(). The initial value of _count is 1. If
these two threads are interleaved in the following order,
thread B misses the signal sent by thread A, because at the
time thread A sends a signal, B is not waiting for it.


  Thread A                 |   Thread B
                           |   std::unique_lock<std::mutex> lock(_condMut);
                           |   while (!(_count == 0)) {
  if (--_count == 0)       |
    _cond_notify_all()     |
                           |     _cond.wait();
                           |   }

Note that "wait(lock, pred)" is equivalent to "while(!pred())
wait(lock)", so I expanded it in the above example.

http://llvm-reviews.chandlerc.com/D764

Files:
  include/lld/Core/Parallel.h

Index: include/lld/Core/Parallel.h
===================================================================
--- include/lld/Core/Parallel.h
+++ include/lld/Core/Parallel.h
@@ -44,16 +44,21 @@
 ///
 /// Calling dec() on a Latch with a count of 0 has undefined behaivor.
 class Latch {
-  std::atomic<uint32_t> _count;
+  uint32_t _count;
   mutable std::mutex _condMut;
   mutable std::condition_variable _cond;
 
 public:
   Latch(uint32_t count = 0) : _count(count) {}
   ~Latch() { sync(); }
-  void inc() { ++_count; }
+
+  void inc() {
+    std::unique_lock<std::mutex> lock(_condMut);
+    ++_count;
+  }
 
   void dec() {
+    std::unique_lock<std::mutex> lock(_condMut);
     if (--_count == 0)
       _cond.notify_all();
   }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D764.1.patch
Type: text/x-patch
Size: 729 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130507/1fdf61da/attachment.bin>


More information about the llvm-commits mailing list