Skip to content

Commit

Permalink
Deprecation of PromoteReadyEventsUnsafe, optimization of a control st…
Browse files Browse the repository at this point in the history
…atement
  • Loading branch information
codemercenary committed Feb 13, 2015
1 parent 02529aa commit 74d9e59
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 21 deletions.
9 changes: 8 additions & 1 deletion autowiring/DispatchQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ class DispatchQueue {
/// <summary>
/// Moves all ready events from the delayed queue into the dispatch queue
/// </summary>
void PromoteReadyEventsUnsafe(void);
/// <returns>True if at least one dispatcher was promoted</returns>
bool PromoteReadyDispatchersUnsafe(void);

// Identical to PromoteReadyDispatchersUnsafe, invoke that method instead
void DEPRECATED(PromoteReadyEventsUnsafe(void), "Superceded by PromoteReadyDispatchersUnsafe") { PromoteReadyDispatchersUnsafe(); }

/// <summary>
/// Similar to DispatchEvent, except assumes that the dispatch lock is currently held
Expand Down Expand Up @@ -132,6 +136,9 @@ class DispatchQueue {
/// Similar to WaitForEvent, but does not block
/// </summary>
/// <returns>True if an event was dispatched, false if the queue was empty when checked</returns>
/// <remarks>
/// If the dispatch queue is empty, this method will check the delayed dispatch queue.
/// </remarks>
bool DispatchEvent(void);

/// <summary>
Expand Down
5 changes: 1 addition & 4 deletions src/autowiring/CoreThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,8 @@ bool CoreThread::WaitForEventUnsafe(std::unique_lock<std::mutex>& lk, std::chron
if(m_aborted)
throw dispatch_aborted_exception();

// Pull over any ready events:
PromoteReadyEventsUnsafe();

// Dispatch events if the queue is now non-empty:
if(!m_dispatchQueue.empty())
if (!PromoteReadyDispatchersUnsafe())
break;

if(status == std::cv_status::timeout)
Expand Down
38 changes: 22 additions & 16 deletions src/autowiring/DispatchQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "stdafx.h"
#include "DispatchQueue.h"
#include "at_exit.h"
#include <assert.h>

dispatch_aborted_exception::dispatch_aborted_exception(void){}
dispatch_aborted_exception::~dispatch_aborted_exception(void){}
Expand All @@ -23,15 +24,19 @@ DispatchQueue::~DispatchQueue(void) {
}
}

void DispatchQueue::PromoteReadyEventsUnsafe(void) {
bool DispatchQueue::PromoteReadyDispatchersUnsafe(void) {
// Move all ready elements out of the delayed queue and into the dispatch queue:
size_t nInitial = m_delayedQueue.size();
for(
auto now = std::chrono::steady_clock::now();
!m_delayedQueue.empty() && m_delayedQueue.top().GetReadyTime() < now;
m_delayedQueue.pop()
)
// This item's ready time has elapsed, we can add it to our dispatch queue now:
m_dispatchQueue.push_back(m_delayedQueue.top().Get());
// This item's ready time has elapsed, we can add it to our dispatch queue now:
m_dispatchQueue.push_back(m_delayedQueue.top().Get());

// Something was promoted if the dispatch queue size is different
return nInitial != m_delayedQueue.size();
}

void DispatchQueue::DispatchEventUnsafe(std::unique_lock<std::mutex>& lk) {
Expand Down Expand Up @@ -74,12 +79,13 @@ void DispatchQueue::Abort(void) {
bool DispatchQueue::DispatchEvent(void) {
std::unique_lock<std::mutex> lk(m_dispatchLock);

// Update queue with delayed events that are ready
PromoteReadyEventsUnsafe();

if (m_dispatchQueue.empty())
// If the queue is empty and we fail to promote anything, return here
// Note that, due to short-circuiting, promotion will not take place if the queue is not empty.
// This behavior is by design.
if (m_dispatchQueue.empty() && !PromoteReadyDispatchersUnsafe())
return false;

assert(!m_dispatchQueue.empty());
DispatchEventUnsafe(lk);
return true;
}
Expand All @@ -104,17 +110,17 @@ void DispatchQueue::AddExisting(DispatchThunkBase* pBase) {
std::chrono::steady_clock::time_point
DispatchQueue::SuggestSoonestWakeupTimeUnsafe(std::chrono::steady_clock::time_point latestTime) const {
return
m_delayedQueue.empty() ?
m_delayedQueue.empty() ?

// Nothing in the queue, no way to suggest a shorter time
latestTime :
// Nothing in the queue, no way to suggest a shorter time
latestTime :

// Return the shorter of the maximum wait time and the time of the queue ready--we don't want to tell the
// caller to wait longer than the limit of their interest.
std::min(
m_delayedQueue.top().GetReadyTime(),
latestTime
);
// Return the shorter of the maximum wait time and the time of the queue ready--we don't want to tell the
// caller to wait longer than the limit of their interest.
std::min(
m_delayedQueue.top().GetReadyTime(),
latestTime
);
}

DispatchQueue::DispatchThunkDelayedExpression DispatchQueue::operator+=(std::chrono::steady_clock::time_point rhs) {
Expand Down

0 comments on commit 74d9e59

Please sign in to comment.