void NA_Timer::waitForElapse() { while (!hasElapsed()) { #ifdef _WIN32 Sleep(250*(duration - difftime(time(NULL), start))); //quarter of a second mulitplied by remianing duration (which is in seconds) #endif } }
void SlotVisitor::drain(MonotonicTime timeout) { ASSERT(m_isInParallelMode); while ((!m_collectorStack.isEmpty() || !m_mutatorStack.isEmpty()) && !hasElapsed(timeout)) { if (!m_collectorStack.isEmpty()) { m_collectorStack.refill(); m_isVisitingMutatorStack = false; for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_collectorStack.canRemoveLast() && countdown--;) visitChildren(m_collectorStack.removeLast()); } else if (!m_mutatorStack.isEmpty()) { m_mutatorStack.refill(); // We know for sure that we are visiting objects because of the barrier, not because of // marking. Marking will visit an object exactly once. The barrier will visit it // possibly many times, and always after it was already marked. m_isVisitingMutatorStack = true; for (unsigned countdown = Options::minimumNumberOfScansBetweenRebalance(); m_mutatorStack.canRemoveLast() && countdown--;) visitChildren(m_mutatorStack.removeLast()); } donateKnownParallel(); } mergeOpaqueRootsIfNecessary(); }
bool Timer::operator<(float value) { return !hasElapsed(value); }
SlotVisitor::SharedDrainResult SlotVisitor::drainFromShared(SharedDrainMode sharedDrainMode, MonotonicTime timeout) { ASSERT(m_isInParallelMode); ASSERT(Options::numberOfGCMarkers()); { std::lock_guard<Lock> lock(m_heap.m_markingMutex); m_heap.m_numberOfActiveParallelMarkers++; } while (true) { { std::unique_lock<Lock> lock(m_heap.m_markingMutex); m_heap.m_numberOfActiveParallelMarkers--; m_heap.m_numberOfWaitingParallelMarkers++; // How we wait differs depending on drain mode. if (sharedDrainMode == MasterDrain) { // Wait until either termination is reached, or until there is some work // for us to do. while (true) { if (hasElapsed(timeout)) return SharedDrainResult::TimedOut; // Did we reach termination? if (!m_heap.m_numberOfActiveParallelMarkers && m_heap.m_sharedCollectorMarkStack->isEmpty() && m_heap.m_sharedMutatorMarkStack->isEmpty()) { // Let any sleeping slaves know it's time for them to return; m_heap.m_markingConditionVariable.notifyAll(); return SharedDrainResult::Done; } // Is there work to be done? if (!m_heap.m_sharedCollectorMarkStack->isEmpty() || !m_heap.m_sharedMutatorMarkStack->isEmpty()) break; // Otherwise wait. m_heap.m_markingConditionVariable.waitUntil(lock, timeout); } } else { ASSERT(sharedDrainMode == SlaveDrain); if (hasElapsed(timeout)) return SharedDrainResult::TimedOut; // Did we detect termination? If so, let the master know. if (!m_heap.m_numberOfActiveParallelMarkers && m_heap.m_sharedCollectorMarkStack->isEmpty() && m_heap.m_sharedMutatorMarkStack->isEmpty()) m_heap.m_markingConditionVariable.notifyAll(); m_heap.m_markingConditionVariable.waitUntil( lock, timeout, [this] { return !m_heap.m_sharedCollectorMarkStack->isEmpty() || !m_heap.m_sharedMutatorMarkStack->isEmpty() || m_heap.m_parallelMarkersShouldExit; }); // Is the current phase done? If so, return from this function. if (m_heap.m_parallelMarkersShouldExit) return SharedDrainResult::Done; } m_collectorStack.stealSomeCellsFrom( *m_heap.m_sharedCollectorMarkStack, m_heap.m_numberOfWaitingParallelMarkers); m_mutatorStack.stealSomeCellsFrom( *m_heap.m_sharedMutatorMarkStack, m_heap.m_numberOfWaitingParallelMarkers); m_heap.m_numberOfActiveParallelMarkers++; m_heap.m_numberOfWaitingParallelMarkers--; } drain(timeout); } }
bool shouldTimeOut() const { return didVisitSomething() && hasElapsed(m_timeout); }