mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
[lld][Core] Fix latch synchronization bug.
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.
Reviewers: Bigcheese
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D764
llvm-svn: 181484
This commit is contained in:
@@ -44,16 +44,21 @@ namespace lld {
|
||||
///
|
||||
/// 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:
|
||||
explicit 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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user