15
15
#include < cerrno>
16
16
17
17
PThreadEvent::PThreadEvent (uint32_t bits, uint32_t validBits)
18
- : m_mutex(), m_set_condition(), m_reset_condition( ), m_bits(bits ),
19
- m_validBits(validBits), m_reset_ack_mask(0 ) {
18
+ : m_mutex(), m_set_condition(), m_bits(bits ), m_validBits(validBits ),
19
+ m_reset_ack_mask(0 ) {
20
20
// DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, 0x%8.8x)",
21
21
// this, __FUNCTION__, bits, validBits);
22
22
}
@@ -27,7 +27,7 @@ PThreadEvent::~PThreadEvent() {
27
27
28
28
uint32_t PThreadEvent::NewEventBit () {
29
29
// DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
30
- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
30
+ std::lock_guard<std::mutex> guard ( m_mutex);
31
31
uint32_t mask = 1 ;
32
32
while (mask & m_validBits)
33
33
mask <<= 1 ;
@@ -39,15 +39,15 @@ void PThreadEvent::FreeEventBits(const uint32_t mask) {
39
39
// DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
40
40
// __FUNCTION__, mask);
41
41
if (mask) {
42
- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
42
+ std::lock_guard<std::mutex> guard ( m_mutex);
43
43
m_bits &= ~mask;
44
44
m_validBits &= ~mask;
45
45
}
46
46
}
47
47
48
48
uint32_t PThreadEvent::GetEventBits () const {
49
49
// DNBLogThreadedIf(LOG_EVENTS, "%p %s", this, LLVM_PRETTY_FUNCTION);
50
- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
50
+ std::lock_guard<std::mutex> guard ( m_mutex);
51
51
uint32_t bits = m_bits;
52
52
return bits;
53
53
}
@@ -56,7 +56,7 @@ uint32_t PThreadEvent::GetEventBits() const {
56
56
void PThreadEvent::ReplaceEventBits (const uint32_t bits) {
57
57
// DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
58
58
// __FUNCTION__, bits);
59
- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
59
+ std::lock_guard<std::mutex> guard ( m_mutex);
60
60
// Make sure we have some bits and that they aren't already set...
61
61
if (m_bits != bits) {
62
62
// Figure out which bits are changing
@@ -65,7 +65,7 @@ void PThreadEvent::ReplaceEventBits(const uint32_t bits) {
65
65
m_bits = bits;
66
66
// If any new bits are set, then broadcast
67
67
if (changed_bits & m_bits)
68
- m_set_condition.Broadcast ();
68
+ m_set_condition.notify_all ();
69
69
}
70
70
}
71
71
@@ -77,14 +77,14 @@ void PThreadEvent::SetEvents(const uint32_t mask) {
77
77
// __FUNCTION__, mask);
78
78
// Make sure we have some bits to set
79
79
if (mask) {
80
- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
80
+ std::lock_guard<std::mutex> guard ( m_mutex);
81
81
// Save the old event bit state so we can tell if things change
82
82
uint32_t old = m_bits;
83
83
// Set the all event bits that are set in 'mask'
84
84
m_bits |= mask;
85
85
// Broadcast only if any extra bits got set.
86
86
if (old != m_bits)
87
- m_set_condition.Broadcast ();
87
+ m_set_condition.notify_all ();
88
88
}
89
89
}
90
90
@@ -93,18 +93,27 @@ void PThreadEvent::ResetEvents(const uint32_t mask) {
93
93
// DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
94
94
// __FUNCTION__, mask);
95
95
if (mask) {
96
- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
97
-
98
- // Save the old event bit state so we can tell if things change
99
- uint32_t old = m_bits;
96
+ std::lock_guard<std::mutex> guard (m_mutex);
100
97
// Clear the all event bits that are set in 'mask'
101
98
m_bits &= ~mask;
102
- // Broadcast only if any extra bits got reset.
103
- if (old != m_bits)
104
- m_reset_condition.Broadcast ();
105
99
}
106
100
}
107
101
102
+ static std::chrono::nanoseconds ToDuration (timespec ts) {
103
+ auto duration =
104
+ std::chrono::seconds{ts.tv_sec } + std::chrono::nanoseconds{ts.tv_nsec };
105
+ return std::chrono::duration_cast<std::chrono::nanoseconds>(duration);
106
+ }
107
+
108
+ static std::chrono::time_point<std::chrono::system_clock,
109
+ std::chrono::nanoseconds>
110
+ ToTimePoint (timespec ts) {
111
+ return std::chrono::time_point<std::chrono::system_clock,
112
+ std::chrono::nanoseconds>{
113
+ std::chrono::duration_cast<std::chrono::system_clock::duration>(
114
+ ToDuration (ts))};
115
+ }
116
+
108
117
// Wait until 'timeout_abstime' for any events that are set in
109
118
// 'mask'. If 'timeout_abstime' is NULL, then wait forever.
110
119
uint32_t
@@ -113,30 +122,17 @@ PThreadEvent::WaitForEventsImpl(const uint32_t mask,
113
122
std::function<bool ()> predicate) const {
114
123
// DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
115
124
// __FUNCTION__, mask, timeout_abstime);
116
-
117
- int err = 0 ;
118
-
119
- // pthread_cond_timedwait() or pthread_cond_wait() will atomically
120
- // unlock the mutex and wait for the condition to be set. When either
121
- // function returns, they will re-lock the mutex. We use an auto lock/unlock
122
- // class (PThreadMutex::Locker) to allow us to return at any point in this
123
- // function and not have to worry about unlocking the mutex.
124
- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
125
-
126
- // Check the predicate and the error code. The functions below do not return
127
- // EINTR so that's not something we need to handle.
128
- while (!predicate () && err == 0 ) {
129
- if (timeout_abstime) {
130
- // Wait for condition to get broadcast, or for a timeout. If we get
131
- // a timeout we will drop out of the loop on the next iteration and we
132
- // will recompute the mask in case of a race between the condition and the
133
- // timeout.
134
- err = ::pthread_cond_timedwait (m_set_condition.Condition (),
135
- m_mutex.Mutex (), timeout_abstime);
136
- } else {
137
- // Wait for condition to get broadcast.
138
- err = ::pthread_cond_wait (m_set_condition.Condition (), m_mutex.Mutex ());
139
- }
125
+ std::unique_lock<std::mutex> lock (m_mutex);
126
+
127
+ if (timeout_abstime) {
128
+ // Wait for condition to get broadcast, or for a timeout. If we get
129
+ // a timeout we will drop out of the loop on the next iteration and we
130
+ // will recompute the mask in case of a race between the condition and the
131
+ // timeout.
132
+ m_set_condition.wait_until (lock, ToTimePoint (*timeout_abstime), predicate);
133
+ } else {
134
+ // Wait for condition to get broadcast.
135
+ m_set_condition.wait (lock, predicate);
140
136
}
141
137
142
138
// Either the predicate passed, we hit the specified timeout (ETIMEDOUT) or we
0 commit comments