blob: 82e9122f4ae25e8adef0c8c8030d40d79449233c (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
//===- lld/Core/TaskGroup.h - Task Group ----------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLD_CORE_TASKGROUP_H
#define LLD_CORE_TASKGROUP_H
#include "lld/Core/LLVM.h"
#include <condition_variable>
#include <functional>
#include <mutex>
namespace lld {
/// \brief Allows one or more threads to wait on a potentially unknown number of
/// events.
///
/// A latch starts at \p count. inc() increments this, and dec() decrements it.
/// All calls to sync() will block while the count is not 0.
///
/// Calling dec() on a Latch with a count of 0 has undefined behaivor.
class Latch {
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() {
std::unique_lock<std::mutex> lock(_condMut);
++_count;
}
void dec() {
std::unique_lock<std::mutex> lock(_condMut);
if (--_count == 0)
_cond.notify_all();
}
void sync() const {
std::unique_lock<std::mutex> lock(_condMut);
_cond.wait(lock, [&] { return _count == 0; });
}
};
/// \brief Allows launching a number of tasks and waiting for them to finish
/// either explicitly via sync() or implicitly on destruction.
class TaskGroup {
Latch _latch;
public:
void spawn(std::function<void()> f);
void sync() const { _latch.sync(); }
};
}
#endif
|