1515#include < cerrno>
1616
1717PThreadEvent::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 ) {
2020 // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, 0x%8.8x)",
2121 // this, __FUNCTION__, bits, validBits);
2222}
@@ -27,7 +27,7 @@ PThreadEvent::~PThreadEvent() {
2727
2828uint32_t PThreadEvent::NewEventBit () {
2929 // 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);
3131 uint32_t mask = 1 ;
3232 while (mask & m_validBits)
3333 mask <<= 1 ;
@@ -39,15 +39,15 @@ void PThreadEvent::FreeEventBits(const uint32_t mask) {
3939 // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
4040 // __FUNCTION__, mask);
4141 if (mask) {
42- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
42+ std::lock_guard<std::mutex> guard ( m_mutex);
4343 m_bits &= ~mask;
4444 m_validBits &= ~mask;
4545 }
4646}
4747
4848uint32_t PThreadEvent::GetEventBits () const {
4949 // 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);
5151 uint32_t bits = m_bits;
5252 return bits;
5353}
@@ -56,7 +56,7 @@ uint32_t PThreadEvent::GetEventBits() const {
5656void PThreadEvent::ReplaceEventBits (const uint32_t bits) {
5757 // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
5858 // __FUNCTION__, bits);
59- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
59+ std::lock_guard<std::mutex> guard ( m_mutex);
6060 // Make sure we have some bits and that they aren't already set...
6161 if (m_bits != bits) {
6262 // Figure out which bits are changing
@@ -65,7 +65,7 @@ void PThreadEvent::ReplaceEventBits(const uint32_t bits) {
6565 m_bits = bits;
6666 // If any new bits are set, then broadcast
6767 if (changed_bits & m_bits)
68- m_set_condition.Broadcast ();
68+ m_set_condition.notify_all ();
6969 }
7070}
7171
@@ -77,14 +77,14 @@ void PThreadEvent::SetEvents(const uint32_t mask) {
7777 // __FUNCTION__, mask);
7878 // Make sure we have some bits to set
7979 if (mask) {
80- PTHREAD_MUTEX_LOCKER (locker, m_mutex);
80+ std::lock_guard<std::mutex> guard ( m_mutex);
8181 // Save the old event bit state so we can tell if things change
8282 uint32_t old = m_bits;
8383 // Set the all event bits that are set in 'mask'
8484 m_bits |= mask;
8585 // Broadcast only if any extra bits got set.
8686 if (old != m_bits)
87- m_set_condition.Broadcast ();
87+ m_set_condition.notify_all ();
8888 }
8989}
9090
@@ -93,18 +93,27 @@ void PThreadEvent::ResetEvents(const uint32_t mask) {
9393 // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x)", this,
9494 // __FUNCTION__, mask);
9595 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);
10097 // Clear the all event bits that are set in 'mask'
10198 m_bits &= ~mask;
102- // Broadcast only if any extra bits got reset.
103- if (old != m_bits)
104- m_reset_condition.Broadcast ();
10599 }
106100}
107101
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+
108117// Wait until 'timeout_abstime' for any events that are set in
109118// 'mask'. If 'timeout_abstime' is NULL, then wait forever.
110119uint32_t
@@ -113,30 +122,17 @@ PThreadEvent::WaitForEventsImpl(const uint32_t mask,
113122 std::function<bool ()> predicate) const {
114123 // DNBLogThreadedIf(LOG_EVENTS, "%p PThreadEvent::%s (0x%8.8x, %p)", this,
115124 // __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);
140136 }
141137
142138 // Either the predicate passed, we hit the specified timeout (ETIMEDOUT) or we
0 commit comments