mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Backed out 4 changesets (bug 1437167) for build bustages on nsUpdateDriver.cpp and WindowsMessageLoop.cpp on a CLOSED TREE.
Backed out changeset b98740e7c639 (bug 1437167) Backed out changeset 4476e8f51fa6 (bug 1437167) Backed out changeset c79dc40faa41 (bug 1437167) Backed out changeset b608d2dcbb86 (bug 1437167)
This commit is contained in:
parent
6731fbe8de
commit
ed1b2a8736
@ -365,7 +365,7 @@ SystemClockDriver::WaitForNextIteration()
|
||||
{
|
||||
mGraphImpl->GetMonitor().AssertCurrentThreadOwns();
|
||||
|
||||
TimeDuration timeout = TimeDuration::Forever();
|
||||
PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
// This lets us avoid hitting the Atomic twice when we know we won't sleep
|
||||
@ -384,7 +384,7 @@ SystemClockDriver::WaitForNextIteration()
|
||||
// Make sure timeoutMS doesn't overflow 32 bits by waking up at
|
||||
// least once a minute, if we need to wake up at all
|
||||
timeoutMS = std::max<int64_t>(0, std::min<int64_t>(timeoutMS, 60*1000));
|
||||
timeout = TimeDuration::FromMilliseconds(timeoutMS);
|
||||
timeout = PR_MillisecondsToInterval(uint32_t(timeoutMS));
|
||||
LOG(LogLevel::Verbose,
|
||||
("Waiting for next iteration; at %f, timeout=%f",
|
||||
(now - mInitialTimeStamp).ToSeconds(),
|
||||
@ -394,7 +394,7 @@ SystemClockDriver::WaitForNextIteration()
|
||||
}
|
||||
mWaitState = WAITSTATE_WAITING_FOR_NEXT_ITERATION;
|
||||
}
|
||||
if (!timeout.IsZero()) {
|
||||
if (timeout > 0) {
|
||||
mGraphImpl->GetMonitor().Wait(timeout);
|
||||
LOG(LogLevel::Verbose,
|
||||
("Resuming after timeout; at %f, elapsed=%f",
|
||||
|
@ -181,6 +181,7 @@ StorageDBThread::StorageDBThread()
|
||||
, mStatus(NS_OK)
|
||||
, mWorkerStatements(mWorkerConnection)
|
||||
, mReaderStatements(mReaderConnection)
|
||||
, mDirtyEpoch(0)
|
||||
, mFlushImmediately(false)
|
||||
, mPriorityCounter(0)
|
||||
{
|
||||
@ -530,8 +531,7 @@ StorageDBThread::ThreadFunc()
|
||||
} while (NS_SUCCEEDED(rv) && processedEvent);
|
||||
}
|
||||
|
||||
TimeDuration timeUntilFlush = TimeUntilFlush();
|
||||
if (MOZ_UNLIKELY(timeUntilFlush.IsZero())) {
|
||||
if (MOZ_UNLIKELY(TimeUntilFlush() == 0)) {
|
||||
// Flush time is up or flush has been forced, do it now.
|
||||
UnscheduleFlush();
|
||||
if (mPendingTasks.Prepare()) {
|
||||
@ -558,7 +558,7 @@ StorageDBThread::ThreadFunc()
|
||||
SetDefaultPriority(); // urgent preload unscheduled
|
||||
}
|
||||
} else if (MOZ_UNLIKELY(!mStopIOThread)) {
|
||||
lockMonitor.Wait(timeUntilFlush);
|
||||
lockMonitor.Wait(TimeUntilFlush());
|
||||
}
|
||||
} // thread loop
|
||||
|
||||
@ -825,7 +825,7 @@ StorageDBThread::ScheduleFlush()
|
||||
}
|
||||
|
||||
// Must be non-zero to indicate we are scheduled
|
||||
mDirtyEpoch = TimeStamp::Now();
|
||||
mDirtyEpoch = PR_IntervalNow() | 1;
|
||||
|
||||
// Wake the monitor from indefinite sleep...
|
||||
(mThreadObserver->GetMonitor()).Notify();
|
||||
@ -836,28 +836,32 @@ StorageDBThread::UnscheduleFlush()
|
||||
{
|
||||
// We are just about to do the flush, drop flags
|
||||
mFlushImmediately = false;
|
||||
mDirtyEpoch = TimeStamp();
|
||||
mDirtyEpoch = 0;
|
||||
}
|
||||
|
||||
TimeDuration
|
||||
PRIntervalTime
|
||||
StorageDBThread::TimeUntilFlush()
|
||||
{
|
||||
if (mFlushImmediately) {
|
||||
return 0; // Do it now regardless the timeout.
|
||||
}
|
||||
|
||||
static_assert(PR_INTERVAL_NO_TIMEOUT != 0,
|
||||
"PR_INTERVAL_NO_TIMEOUT must be non-zero");
|
||||
|
||||
if (!mDirtyEpoch) {
|
||||
return TimeDuration::Forever(); // No pending task...
|
||||
return PR_INTERVAL_NO_TIMEOUT; // No pending task...
|
||||
}
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
TimeDuration age = now - mDirtyEpoch;
|
||||
static const TimeDuration kMaxAge = TimeDuration::FromMilliseconds(FLUSHING_INTERVAL_MS);
|
||||
static const PRIntervalTime kMaxAge = PR_MillisecondsToInterval(FLUSHING_INTERVAL_MS);
|
||||
|
||||
PRIntervalTime now = PR_IntervalNow() | 1;
|
||||
PRIntervalTime age = now - mDirtyEpoch;
|
||||
if (age > kMaxAge) {
|
||||
return 0; // It is time.
|
||||
}
|
||||
|
||||
return kMaxAge - age; // Time left. This is used to sleep the monitor.
|
||||
return kMaxAge - age; // Time left, this is used to sleep the monitor
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/BasePrincipal.h"
|
||||
#include "mozilla/storage/StatementCache.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -441,7 +440,7 @@ private:
|
||||
|
||||
// Time the first pending operation has been added to the pending operations
|
||||
// list
|
||||
TimeStamp mDirtyEpoch;
|
||||
PRIntervalTime mDirtyEpoch;
|
||||
|
||||
// Flag to force immediate flush of all pending operations
|
||||
bool mFlushImmediately;
|
||||
@ -487,12 +486,12 @@ private:
|
||||
// 2. as in indicator that flush has to be performed
|
||||
//
|
||||
// Return:
|
||||
// - TimeDuration::Forever() when no pending tasks are scheduled
|
||||
// - Non-zero TimeDuration when tasks have been scheduled, but it
|
||||
// is still not time to perform the flush ; it is actual time to
|
||||
// wait until the flush has to happen.
|
||||
// - 0 TimeDuration when it is time to do the flush
|
||||
TimeDuration TimeUntilFlush();
|
||||
// - PR_INTERVAL_NO_TIMEOUT when no pending tasks are scheduled
|
||||
// - larger then zero when tasks have been scheduled, but it is
|
||||
// still not time to perform the flush ; it is actual interval
|
||||
// time to wait until the flush has to happen
|
||||
// - 0 when it is time to do the flush
|
||||
PRIntervalTime TimeUntilFlush();
|
||||
|
||||
// Notifies to the main thread that flush has completed
|
||||
void NotifyFlushCompletion();
|
||||
|
@ -3614,7 +3614,7 @@ WorkerPrivate::InterruptCallback(JSContext* aCx)
|
||||
break;
|
||||
}
|
||||
|
||||
WaitForWorkerEvents();
|
||||
WaitForWorkerEvents(PR_MillisecondsToInterval(UINT32_MAX));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3735,13 +3735,13 @@ WorkerPrivate::DisableMemoryReporter()
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::WaitForWorkerEvents()
|
||||
WorkerPrivate::WaitForWorkerEvents(PRIntervalTime aInterval)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
|
||||
// Wait for a worker event.
|
||||
mCondVar.Wait();
|
||||
mCondVar.Wait(aInterval);
|
||||
}
|
||||
|
||||
WorkerPrivate::ProcessAllControlRunnablesResult
|
||||
|
@ -1274,7 +1274,7 @@ private:
|
||||
DisableMemoryReporter();
|
||||
|
||||
void
|
||||
WaitForWorkerEvents();
|
||||
WaitForWorkerEvents(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
|
||||
|
||||
void
|
||||
PostMessageToParentInternal(JSContext* aCx,
|
||||
|
@ -49,7 +49,8 @@ public:
|
||||
|
||||
{ // scope lock
|
||||
MonitorAutoLock lock(mVsyncMonitor);
|
||||
lock.Wait(TimeDuration::FromMilliseconds(kVsyncTimeoutMS));
|
||||
PRIntervalTime timeout = PR_MillisecondsToInterval(kVsyncTimeoutMS);
|
||||
lock.Wait(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIThreadPool.h"
|
||||
@ -59,7 +58,7 @@ public:
|
||||
|
||||
DecodePoolImpl(uint8_t aMaxThreads,
|
||||
uint8_t aMaxIdleThreads,
|
||||
TimeDuration aIdleTimeout)
|
||||
PRIntervalTime aIdleTimeout)
|
||||
: mMonitor("DecodePoolImpl")
|
||||
, mThreads(aMaxThreads)
|
||||
, mIdleTimeout(aIdleTimeout)
|
||||
@ -173,7 +172,7 @@ private:
|
||||
{
|
||||
mMonitor.AssertCurrentThreadOwns();
|
||||
|
||||
TimeDuration timeout = mIdleTimeout;
|
||||
PRIntervalTime timeout = mIdleTimeout;
|
||||
do {
|
||||
if (!mHighPriorityQueue.IsEmpty()) {
|
||||
return PopWorkFromQueue(mHighPriorityQueue);
|
||||
@ -198,19 +197,19 @@ private:
|
||||
// This thread should shutdown if it is idle. If we have waited longer
|
||||
// than the timeout period without having done any work, then we should
|
||||
// shutdown the thread.
|
||||
if (timeout.IsZero()) {
|
||||
if (timeout == 0) {
|
||||
return CreateShutdownWork();
|
||||
}
|
||||
|
||||
++mIdleThreads;
|
||||
MOZ_ASSERT(mIdleThreads <= mThreads.Capacity());
|
||||
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
PRIntervalTime now = PR_IntervalNow();
|
||||
mMonitor.Wait(timeout);
|
||||
TimeDuration delta = TimeStamp::Now() - now;
|
||||
PRIntervalTime delta = PR_IntervalNow() - now;
|
||||
if (delta > timeout) {
|
||||
timeout = 0;
|
||||
} else if (timeout != TimeDuration::Forever()) {
|
||||
} else {
|
||||
timeout -= delta;
|
||||
}
|
||||
}
|
||||
@ -248,7 +247,7 @@ private:
|
||||
nsTArray<RefPtr<IDecodingTask>> mHighPriorityQueue;
|
||||
nsTArray<RefPtr<IDecodingTask>> mLowPriorityQueue;
|
||||
nsTArray<nsCOMPtr<nsIThread>> mThreads;
|
||||
TimeDuration mIdleTimeout;
|
||||
PRIntervalTime mIdleTimeout;
|
||||
uint8_t mMaxIdleThreads; // Maximum number of workers when idle.
|
||||
uint8_t mAvailableThreads; // How many new threads can be created.
|
||||
uint8_t mIdleThreads; // How many created threads are waiting.
|
||||
@ -384,12 +383,12 @@ DecodePool::DecodePool()
|
||||
|
||||
// The timeout period before shutting down idle threads.
|
||||
int32_t prefIdleTimeout = gfxPrefs::ImageMTDecodingIdleTimeout();
|
||||
TimeDuration idleTimeout;
|
||||
PRIntervalTime idleTimeout;
|
||||
if (prefIdleTimeout <= 0) {
|
||||
idleTimeout = TimeDuration::Forever();
|
||||
idleTimeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
idleLimit = limit;
|
||||
} else {
|
||||
idleTimeout = TimeDuration::FromMilliseconds(prefIdleTimeout);
|
||||
idleTimeout = PR_MillisecondsToInterval(static_cast<uint32_t>(prefIdleTimeout));
|
||||
idleLimit = (limit + 1) / 2;
|
||||
}
|
||||
|
||||
|
@ -372,12 +372,12 @@ GeckoChildProcessHost::WaitUntilConnected(int32_t aTimeoutMs)
|
||||
|
||||
// NB: this uses a different mechanism than the chromium parent
|
||||
// class.
|
||||
TimeDuration timeout = (aTimeoutMs > 0) ?
|
||||
TimeDuration::FromMilliseconds(aTimeoutMs) : TimeDuration::Forever();
|
||||
PRIntervalTime timeoutTicks = (aTimeoutMs > 0) ?
|
||||
PR_MillisecondsToInterval(aTimeoutMs) : PR_INTERVAL_NO_TIMEOUT;
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
TimeStamp waitStart = TimeStamp::Now();
|
||||
TimeStamp current;
|
||||
PRIntervalTime waitStart = PR_IntervalNow();
|
||||
PRIntervalTime current;
|
||||
|
||||
// We'll receive several notifications, we need to exit when we
|
||||
// have either successfully launched or have timed out.
|
||||
@ -387,14 +387,15 @@ GeckoChildProcessHost::WaitUntilConnected(int32_t aTimeoutMs)
|
||||
break;
|
||||
}
|
||||
|
||||
CVStatus status = lock.Wait(timeout);
|
||||
if (status == CVStatus::Timeout) {
|
||||
break;
|
||||
}
|
||||
lock.Wait(timeoutTicks);
|
||||
|
||||
if (timeout != TimeDuration::Forever()) {
|
||||
current = TimeStamp::Now();
|
||||
timeout -= current - waitStart;
|
||||
if (timeoutTicks != PR_INTERVAL_NO_TIMEOUT) {
|
||||
current = PR_IntervalNow();
|
||||
PRIntervalTime elapsed = current - waitStart;
|
||||
if (elapsed > timeoutTicks) {
|
||||
break;
|
||||
}
|
||||
timeoutTicks = timeoutTicks - elapsed;
|
||||
waitStart = current;
|
||||
}
|
||||
}
|
||||
|
@ -2316,6 +2316,13 @@ MessageChannel::EnqueuePendingMessages()
|
||||
RepostAllMessages();
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsTimeoutExpired(PRIntervalTime aStart, PRIntervalTime aTimeout)
|
||||
{
|
||||
return (aTimeout != PR_INTERVAL_NO_TIMEOUT) &&
|
||||
(aTimeout <= (PR_IntervalNow() - aStart));
|
||||
}
|
||||
|
||||
bool
|
||||
MessageChannel::WaitResponse(bool aWaitTimedOut)
|
||||
{
|
||||
@ -2345,14 +2352,17 @@ MessageChannel::WaitForSyncNotify(bool /* aHandleWindowsMessages */)
|
||||
}
|
||||
#endif
|
||||
|
||||
TimeDuration timeout = (kNoTimeout == mTimeoutMs) ?
|
||||
TimeDuration::Forever() :
|
||||
TimeDuration::FromMilliseconds(mTimeoutMs);
|
||||
CVStatus status = mMonitor->Wait(timeout);
|
||||
PRIntervalTime timeout = (kNoTimeout == mTimeoutMs) ?
|
||||
PR_INTERVAL_NO_TIMEOUT :
|
||||
PR_MillisecondsToInterval(mTimeoutMs);
|
||||
// XXX could optimize away this syscall for "no timeout" case if desired
|
||||
PRIntervalTime waitStart = PR_IntervalNow();
|
||||
|
||||
mMonitor->Wait(timeout);
|
||||
|
||||
// If the timeout didn't expire, we know we received an event. The
|
||||
// converse is not true.
|
||||
return WaitResponse(status == CVStatus::Timeout);
|
||||
return WaitResponse(IsTimeoutExpired(waitStart, timeout));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -846,6 +846,13 @@ MessageChannel::SpinInternalEventLoop()
|
||||
} while (true);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
IsTimeoutExpired(PRIntervalTime aStart, PRIntervalTime aTimeout)
|
||||
{
|
||||
return (aTimeout != PR_INTERVAL_NO_TIMEOUT) &&
|
||||
(aTimeout <= (PR_IntervalNow() - aStart));
|
||||
}
|
||||
|
||||
static HHOOK gWindowHook;
|
||||
|
||||
static inline void
|
||||
@ -1023,21 +1030,27 @@ MessageChannel::WaitForSyncNotify(bool aHandleWindowsMessages)
|
||||
// Use a blocking wait if this channel does not require
|
||||
// Windows message deferral behavior.
|
||||
if (!(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION) || !aHandleWindowsMessages) {
|
||||
TimeDuration timeout = (kNoTimeout == mTimeoutMs) ?
|
||||
TimeDuration::Forever() :
|
||||
TimeDuration::FromMilliseconds(mTimeoutMs);
|
||||
PRIntervalTime timeout = (kNoTimeout == mTimeoutMs) ?
|
||||
PR_INTERVAL_NO_TIMEOUT :
|
||||
PR_MillisecondsToInterval(mTimeoutMs);
|
||||
PRIntervalTime waitStart = 0;
|
||||
|
||||
if (timeout != PR_INTERVAL_NO_TIMEOUT) {
|
||||
waitStart = PR_IntervalNow();
|
||||
}
|
||||
|
||||
MOZ_ASSERT(!mIsSyncWaitingOnNonMainThread);
|
||||
mIsSyncWaitingOnNonMainThread = true;
|
||||
|
||||
CVStatus status = mMonitor->Wait(timeout);
|
||||
mMonitor->Wait(timeout);
|
||||
|
||||
MOZ_ASSERT(mIsSyncWaitingOnNonMainThread);
|
||||
mIsSyncWaitingOnNonMainThread = false;
|
||||
|
||||
// If the timeout didn't expire, we know we received an event. The
|
||||
// converse is not true.
|
||||
return WaitResponse(status == CVStatus::Timeout);
|
||||
return WaitResponse(timeout == PR_INTERVAL_NO_TIMEOUT ?
|
||||
false : IsTimeoutExpired(waitStart, timeout));
|
||||
}
|
||||
|
||||
NS_ASSERTION(mFlags & REQUIRE_DEFERRED_MESSAGE_PROTECTION,
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
// encounter substantially longer delays, depending on system load.
|
||||
CVStatus wait_for(UniqueLock<Mutex>& lock,
|
||||
const mozilla::TimeDuration& rel_time) {
|
||||
return impl_.wait_for(lock.lock, rel_time) == mozilla::CVStatus::Timeout
|
||||
return impl_.wait_for(lock.lock, rel_time) == mozilla::detail::CVStatus::Timeout
|
||||
? CVStatus::Timeout : CVStatus::NoTimeout;
|
||||
}
|
||||
|
||||
|
@ -695,7 +695,7 @@ ScriptPreloader::Run()
|
||||
// since that can trigger a new write during shutdown, and we don't want to
|
||||
// cause shutdown hangs.
|
||||
if (!mCacheInvalidated) {
|
||||
mal.Wait(TimeDuration::FromSeconds(10));
|
||||
mal.Wait(10000);
|
||||
}
|
||||
|
||||
auto result = URLPreloader::GetSingleton().WriteCache();
|
||||
|
@ -119,7 +119,7 @@ mozilla::detail::ConditionVariableImpl::wait(MutexImpl& lock)
|
||||
MOZ_RELEASE_ASSERT(r == 0);
|
||||
}
|
||||
|
||||
mozilla::CVStatus
|
||||
mozilla::detail::CVStatus
|
||||
mozilla::detail::ConditionVariableImpl::wait_for(MutexImpl& lock,
|
||||
const TimeDuration& a_rel_time)
|
||||
{
|
||||
|
@ -59,35 +59,21 @@ mozilla::detail::ConditionVariableImpl::wait(MutexImpl& lock)
|
||||
MOZ_RELEASE_ASSERT(r);
|
||||
}
|
||||
|
||||
mozilla::CVStatus
|
||||
mozilla::detail::CVStatus
|
||||
mozilla::detail::ConditionVariableImpl::wait_for(MutexImpl& lock,
|
||||
const mozilla::TimeDuration& rel_time)
|
||||
{
|
||||
if (rel_time == mozilla::TimeDuration::Forever()) {
|
||||
wait(lock);
|
||||
return CVStatus::NoTimeout;
|
||||
}
|
||||
|
||||
CRITICAL_SECTION* cs = &lock.platformData()->criticalSection;
|
||||
|
||||
// Note that DWORD is unsigned, so we have to be careful to clamp at 0. If
|
||||
// rel_time is Forever, then ToMilliseconds is +inf, which evaluates as
|
||||
// greater than UINT32_MAX, resulting in the correct INFINITE wait. We also
|
||||
// don't want to round sub-millisecond waits to 0, as that wastes energy (see
|
||||
// bug 1437167 comment 6), so we instead round submillisecond waits to 1ms.
|
||||
// Note that DWORD is unsigned, so we have to be careful to clamp at 0.
|
||||
// If rel_time is Forever, then ToMilliseconds is +inf, which evaluates as
|
||||
// greater than UINT32_MAX, resulting in the correct INFINITE wait.
|
||||
double msecd = rel_time.ToMilliseconds();
|
||||
DWORD msec;
|
||||
if (msecd < 0.0) {
|
||||
msec = 0;
|
||||
} else if (msecd > UINT32_MAX) {
|
||||
msec = INFINITE;
|
||||
} else {
|
||||
msec = static_cast<DWORD>(msecd);
|
||||
// Round submillisecond waits to 1ms.
|
||||
if (msec == 0 && !rel_time.IsZero()) {
|
||||
msec = 1;
|
||||
}
|
||||
}
|
||||
DWORD msec = msecd < 0.0
|
||||
? 0
|
||||
: msecd > UINT32_MAX
|
||||
? INFINITE
|
||||
: static_cast<DWORD>(msecd);
|
||||
|
||||
BOOL r = SleepConditionVariableCS(&platformData()->cv_, cs, msec);
|
||||
if (r)
|
||||
|
@ -19,13 +19,13 @@
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum class CVStatus {
|
||||
NoTimeout,
|
||||
Timeout
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
class ConditionVariableImpl {
|
||||
public:
|
||||
struct PlatformData;
|
||||
|
@ -1677,7 +1677,8 @@ private:
|
||||
nsresult rv = mTaskQueue->Dispatch(runnable.forget());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
lock.Wait();
|
||||
rv = lock.Wait();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mCompleted = true;
|
||||
return mAsyncResult;
|
||||
|
@ -1614,7 +1614,7 @@ class nsAsyncBridgeRequest final : public nsPACManCallback
|
||||
|
||||
void Lock() { mMutex.Lock(); }
|
||||
void Unlock() { mMutex.Unlock(); }
|
||||
void Wait() { mCondVar.Wait(TimeDuration::FromSeconds(3)); }
|
||||
void Wait() { mCondVar.Wait(PR_SecondsToInterval(3)); }
|
||||
|
||||
private:
|
||||
~nsAsyncBridgeRequest()
|
||||
|
@ -578,7 +578,7 @@ public:
|
||||
this, CacheIOThread::WRITE); // When writes and closing of handles is done
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
TimeDuration waitTime = TimeDuration::FromSeconds(1);
|
||||
PRIntervalTime const waitTime = PR_MillisecondsToInterval(1000);
|
||||
while (!mNotified) {
|
||||
mon.Wait(waitTime);
|
||||
if (!mNotified) {
|
||||
|
@ -519,7 +519,7 @@ loopStart:
|
||||
break;
|
||||
}
|
||||
|
||||
lock.Wait();
|
||||
lock.Wait(PR_INTERVAL_NO_TIMEOUT);
|
||||
|
||||
} while (true);
|
||||
|
||||
|
@ -524,8 +524,8 @@ nsHostResolver::nsHostResolver(uint32_t maxCacheEntries,
|
||||
{
|
||||
mCreationTime = PR_Now();
|
||||
|
||||
mLongIdleTimeout = TimeDuration::FromSeconds(LongIdleTimeoutSeconds);
|
||||
mShortIdleTimeout = TimeDuration::FromSeconds(ShortIdleTimeoutSeconds);
|
||||
mLongIdleTimeout = PR_SecondsToInterval(LongIdleTimeoutSeconds);
|
||||
mShortIdleTimeout = PR_SecondsToInterval(ShortIdleTimeoutSeconds);
|
||||
}
|
||||
|
||||
nsHostResolver::~nsHostResolver() = default;
|
||||
@ -1297,13 +1297,12 @@ bool
|
||||
nsHostResolver::GetHostToLookup(nsHostRecord **result)
|
||||
{
|
||||
bool timedOut = false;
|
||||
TimeDuration timeout;
|
||||
TimeStamp epoch, now;
|
||||
PRIntervalTime epoch, now, timeout;
|
||||
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
timeout = (mNumIdleThreads >= HighThreadThreshold) ? mShortIdleTimeout : mLongIdleTimeout;
|
||||
epoch = TimeStamp::Now();
|
||||
epoch = PR_IntervalNow();
|
||||
|
||||
while (!mShutdown) {
|
||||
// remove next record from Q; hand over owning reference. Check high, then med, then low
|
||||
@ -1348,16 +1347,15 @@ nsHostResolver::GetHostToLookup(nsHostRecord **result)
|
||||
mIdleThreadCV.Wait(timeout);
|
||||
mNumIdleThreads--;
|
||||
|
||||
now = TimeStamp::Now();
|
||||
now = PR_IntervalNow();
|
||||
|
||||
if (now - epoch >= timeout) {
|
||||
if ((PRIntervalTime)(now - epoch) >= timeout)
|
||||
timedOut = true;
|
||||
} else {
|
||||
// It is possible that CondVar::Wait() was interrupted and returned
|
||||
// early, in which case we will loop back and re-enter it. In that
|
||||
// case we want to do so with the new timeout reduced to reflect
|
||||
// time already spent waiting.
|
||||
timeout -= now - epoch;
|
||||
else {
|
||||
// It is possible that PR_WaitCondVar() was interrupted and returned early,
|
||||
// in which case we will loop back and re-enter it. In that case we want to
|
||||
// do so with the new timeout reduced to reflect time already spent waiting.
|
||||
timeout -= (PRIntervalTime)(now - epoch);
|
||||
epoch = now;
|
||||
}
|
||||
}
|
||||
|
@ -444,8 +444,8 @@ private:
|
||||
mozilla::LinkedList<RefPtr<nsHostRecord>> mEvictionQ;
|
||||
uint32_t mEvictionQSize;
|
||||
PRTime mCreationTime;
|
||||
mozilla::TimeDuration mLongIdleTimeout;
|
||||
mozilla::TimeDuration mShortIdleTimeout;
|
||||
PRIntervalTime mLongIdleTimeout;
|
||||
PRIntervalTime mShortIdleTimeout;
|
||||
|
||||
mozilla::Atomic<bool> mShutdown;
|
||||
mozilla::Atomic<uint32_t> mNumIdleThreads;
|
||||
|
@ -591,7 +591,10 @@ DataStorage::WaitForReady()
|
||||
|
||||
MonitorAutoLock readyLock(mReadyMonitor);
|
||||
while (!mReady) {
|
||||
readyLock.Wait();
|
||||
nsresult rv = readyLock.Wait();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(mReady);
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ nsNSSHttpRequestSession::internal_send_receive_attempt(bool &retryable_error,
|
||||
MutexAutoLock locker(waitLock);
|
||||
|
||||
const TimeStamp startTime = TimeStamp::NowLoRes();
|
||||
TimeDuration wait_interval;
|
||||
PRIntervalTime wait_interval;
|
||||
|
||||
bool running_on_main_thread = NS_IsMainThread();
|
||||
if (running_on_main_thread)
|
||||
@ -440,13 +440,13 @@ nsNSSHttpRequestSession::internal_send_receive_attempt(bool &retryable_error,
|
||||
NS_WARNING("Security network blocking I/O on Main Thread");
|
||||
|
||||
// let's process events quickly
|
||||
wait_interval = TimeDuration::FromMicroseconds(50);
|
||||
wait_interval = PR_MicrosecondsToInterval(50);
|
||||
}
|
||||
else
|
||||
{
|
||||
// On a secondary thread, it's fine to wait some more for
|
||||
// for the condition variable.
|
||||
wait_interval = TimeDuration::FromMilliseconds(250);
|
||||
wait_interval = PR_MillisecondsToInterval(250);
|
||||
}
|
||||
|
||||
while (waitFlag)
|
||||
|
@ -1102,7 +1102,10 @@ nsNSSComponent::BlockUntilLoadableRootsLoaded()
|
||||
{
|
||||
MonitorAutoLock rootsLoadedLock(mLoadableRootsLoadedMonitor);
|
||||
while (!mLoadableRootsLoaded) {
|
||||
rootsLoadedLock.Wait();
|
||||
nsresult rv = rootsLoadedLock.Wait();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(mLoadableRootsLoaded);
|
||||
|
||||
|
@ -98,7 +98,7 @@ public:
|
||||
// Lock for access to members of this class
|
||||
Monitor mLock;
|
||||
// Current time as seen by hang monitors
|
||||
TimeStamp mNow;
|
||||
PRIntervalTime mIntervalNow;
|
||||
// List of BackgroundHangThread instances associated with each thread
|
||||
LinkedList<BackgroundHangThread> mHangThreads;
|
||||
// A reference to the StreamTransportService. This is gotten on the main
|
||||
@ -182,14 +182,14 @@ public:
|
||||
sTlsKeyInitialized = sTlsKey.init();
|
||||
}
|
||||
|
||||
// Hang timeout
|
||||
const TimeDuration mTimeout;
|
||||
// PermaHang timeout
|
||||
const TimeDuration mMaxTimeout;
|
||||
// Hang timeout in ticks
|
||||
const PRIntervalTime mTimeout;
|
||||
// PermaHang timeout in ticks
|
||||
const PRIntervalTime mMaxTimeout;
|
||||
// Time at last activity
|
||||
TimeStamp mLastActivity;
|
||||
PRIntervalTime mInterval;
|
||||
// Time when a hang started
|
||||
TimeStamp mHangStart;
|
||||
PRIntervalTime mHangStart;
|
||||
// Is the thread in a hang
|
||||
bool mHanging;
|
||||
// Is the thread in a waiting state
|
||||
@ -218,7 +218,7 @@ public:
|
||||
|
||||
// Report a hang; aManager->mLock IS locked. The hang will be processed
|
||||
// off-main-thread, and will then be submitted back.
|
||||
void ReportHang(TimeDuration aHangTime);
|
||||
void ReportHang(PRIntervalTime aHangTime);
|
||||
// Report a permanent hang; aManager->mLock IS locked
|
||||
void ReportPermaHang();
|
||||
// Called by BackgroundHangMonitor::NotifyActivity
|
||||
@ -256,6 +256,7 @@ bool BackgroundHangThread::sTlsKeyInitialized;
|
||||
BackgroundHangManager::BackgroundHangManager()
|
||||
: mShutdown(false)
|
||||
, mLock("BackgroundHangManager")
|
||||
, mIntervalNow(0)
|
||||
, mSTS(do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID))
|
||||
{
|
||||
// Lock so we don't race against the new monitor thread
|
||||
@ -287,25 +288,25 @@ BackgroundHangManager::RunMonitorThread()
|
||||
// Keep us locked except when waiting
|
||||
MonitorAutoLock autoLock(mLock);
|
||||
|
||||
/* mNow is updated at various intervals determined by waitTime.
|
||||
/* mIntervalNow is updated at various intervals determined by waitTime.
|
||||
However, if an update latency is too long (due to CPU scheduling, system
|
||||
sleep, etc.), we don't update mNow at all. This is done so that
|
||||
sleep, etc.), we don't update mIntervalNow at all. This is done so that
|
||||
long latencies in our timing are not detected as hangs. systemTime is
|
||||
used to track TimeStamp::Now() and determine our latency. */
|
||||
used to track PR_IntervalNow() and determine our latency. */
|
||||
|
||||
TimeStamp systemTime = TimeStamp::Now();
|
||||
PRIntervalTime systemTime = PR_IntervalNow();
|
||||
// Default values for the first iteration of thread loop
|
||||
TimeDuration waitTime;
|
||||
TimeDuration recheckTimeout;
|
||||
TimeStamp lastCheckedCPUUsage = systemTime;
|
||||
TimeDuration checkCPUUsageInterval =
|
||||
TimeDuration::FromMilliseconds(kCheckCPUIntervalMilliseconds);
|
||||
PRIntervalTime waitTime = PR_INTERVAL_NO_WAIT;
|
||||
PRIntervalTime recheckTimeout = PR_INTERVAL_NO_WAIT;
|
||||
PRIntervalTime lastCheckedCPUUsage = systemTime;
|
||||
PRIntervalTime checkCPUUsageInterval =
|
||||
PR_MillisecondsToInterval(kCheckCPUIntervalMilliseconds);
|
||||
|
||||
while (!mShutdown) {
|
||||
autoLock.Wait(waitTime);
|
||||
nsresult rv = autoLock.Wait(waitTime);
|
||||
|
||||
TimeStamp newTime = TimeStamp::Now();
|
||||
TimeDuration systemInterval = newTime - systemTime;
|
||||
PRIntervalTime newTime = PR_IntervalNow();
|
||||
PRIntervalTime systemInterval = newTime - systemTime;
|
||||
systemTime = newTime;
|
||||
|
||||
if (systemTime - lastCheckedCPUUsage > checkCPUUsageInterval) {
|
||||
@ -315,17 +316,18 @@ BackgroundHangManager::RunMonitorThread()
|
||||
|
||||
/* waitTime is a quarter of the shortest timeout value; If our timing
|
||||
latency is low enough (less than half the shortest timeout value),
|
||||
we can update mNow. */
|
||||
if (MOZ_LIKELY(waitTime != TimeDuration::Forever() &&
|
||||
systemInterval < waitTime * 2)) {
|
||||
mNow += systemInterval;
|
||||
we can update mIntervalNow. */
|
||||
if (MOZ_LIKELY(waitTime != PR_INTERVAL_NO_TIMEOUT &&
|
||||
systemInterval < 2 * waitTime)) {
|
||||
mIntervalNow += systemInterval;
|
||||
}
|
||||
|
||||
/* If it's before the next recheck timeout, and our wait did not get
|
||||
interrupted, we can keep the current waitTime and skip iterating
|
||||
through hang monitors. */
|
||||
if (MOZ_LIKELY(systemInterval < recheckTimeout &&
|
||||
systemInterval >= waitTime)) {
|
||||
systemInterval >= waitTime &&
|
||||
rv == NS_OK)) {
|
||||
recheckTimeout -= systemInterval;
|
||||
continue;
|
||||
}
|
||||
@ -336,11 +338,11 @@ BackgroundHangManager::RunMonitorThread()
|
||||
- Thread wait or hang ended
|
||||
In all cases, we want to go through our list of hang
|
||||
monitors and update waitTime and recheckTimeout. */
|
||||
waitTime = TimeDuration::Forever();
|
||||
recheckTimeout = TimeDuration::Forever();
|
||||
waitTime = PR_INTERVAL_NO_TIMEOUT;
|
||||
recheckTimeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
|
||||
// Locally hold mNow
|
||||
TimeStamp now = mNow;
|
||||
// Locally hold mIntervalNow
|
||||
PRIntervalTime intervalNow = mIntervalNow;
|
||||
|
||||
// iterate through hang monitors
|
||||
for (BackgroundHangThread* currentThread = mHangThreads.getFirst();
|
||||
@ -350,8 +352,8 @@ BackgroundHangManager::RunMonitorThread()
|
||||
// Thread is waiting, not hanging
|
||||
continue;
|
||||
}
|
||||
TimeStamp lastActivity = currentThread->mLastActivity;
|
||||
TimeDuration hangTime = now - lastActivity;
|
||||
PRIntervalTime interval = currentThread->mInterval;
|
||||
PRIntervalTime hangTime = intervalNow - interval;
|
||||
if (MOZ_UNLIKELY(hangTime >= currentThread->mMaxTimeout)) {
|
||||
// A permahang started
|
||||
// Skip subsequent iterations and tolerate a race on mWaiting here
|
||||
@ -380,15 +382,15 @@ BackgroundHangManager::RunMonitorThread()
|
||||
lastCheckedCPUUsage = systemTime;
|
||||
}
|
||||
|
||||
currentThread->mHangStart = lastActivity;
|
||||
currentThread->mHangStart = interval;
|
||||
currentThread->mHanging = true;
|
||||
currentThread->mAnnotations =
|
||||
currentThread->mAnnotators.GatherAnnotations();
|
||||
}
|
||||
} else {
|
||||
if (MOZ_LIKELY(lastActivity != currentThread->mHangStart)) {
|
||||
if (MOZ_LIKELY(interval != currentThread->mHangStart)) {
|
||||
// A hang ended
|
||||
currentThread->ReportHang(now - currentThread->mHangStart);
|
||||
currentThread->ReportHang(intervalNow - currentThread->mHangStart);
|
||||
currentThread->mHanging = false;
|
||||
}
|
||||
}
|
||||
@ -396,18 +398,18 @@ BackgroundHangManager::RunMonitorThread()
|
||||
/* If we are hanging, the next time we check for hang status is when
|
||||
the hang turns into a permahang. If we're not hanging, the next
|
||||
recheck timeout is when we may be entering a hang. */
|
||||
TimeDuration nextRecheck;
|
||||
PRIntervalTime nextRecheck;
|
||||
if (currentThread->mHanging) {
|
||||
nextRecheck = currentThread->mMaxTimeout;
|
||||
} else {
|
||||
nextRecheck = currentThread->mTimeout;
|
||||
}
|
||||
recheckTimeout = TimeDuration::Min(recheckTimeout, nextRecheck - hangTime);
|
||||
recheckTimeout = std::min(recheckTimeout, nextRecheck - hangTime);
|
||||
|
||||
if (currentThread->mTimeout != TimeDuration::Forever()) {
|
||||
if (currentThread->mTimeout != PR_INTERVAL_NO_TIMEOUT) {
|
||||
/* We wait for a quarter of the shortest timeout
|
||||
value to give mNow enough granularity. */
|
||||
waitTime = TimeDuration::Min(waitTime, currentThread->mTimeout / (int64_t) 4);
|
||||
value to give mIntervalNow enough granularity. */
|
||||
waitTime = std::min(waitTime, currentThread->mTimeout / 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -415,7 +417,7 @@ BackgroundHangManager::RunMonitorThread()
|
||||
/* We are shutting down now.
|
||||
Wait for all outstanding monitors to unregister. */
|
||||
while (!mHangThreads.isEmpty()) {
|
||||
autoLock.Wait();
|
||||
autoLock.Wait(PR_INTERVAL_NO_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -427,13 +429,13 @@ BackgroundHangThread::BackgroundHangThread(const char* aName,
|
||||
: mManager(BackgroundHangManager::sInstance)
|
||||
, mThreadID(PR_GetCurrentThread())
|
||||
, mTimeout(aTimeoutMs == BackgroundHangMonitor::kNoTimeout
|
||||
? TimeDuration::Forever()
|
||||
: TimeDuration::FromMilliseconds(aTimeoutMs))
|
||||
? PR_INTERVAL_NO_TIMEOUT
|
||||
: PR_MillisecondsToInterval(aTimeoutMs))
|
||||
, mMaxTimeout(aMaxTimeoutMs == BackgroundHangMonitor::kNoTimeout
|
||||
? TimeDuration::Forever()
|
||||
: TimeDuration::FromMilliseconds(aMaxTimeoutMs))
|
||||
, mLastActivity(mManager->mNow)
|
||||
, mHangStart(mLastActivity)
|
||||
? PR_INTERVAL_NO_TIMEOUT
|
||||
: PR_MillisecondsToInterval(aMaxTimeoutMs))
|
||||
, mInterval(mManager->mIntervalNow)
|
||||
, mHangStart(mInterval)
|
||||
, mHanging(false)
|
||||
, mWaiting(true)
|
||||
, mThreadType(aThreadType)
|
||||
@ -466,7 +468,7 @@ BackgroundHangThread::~BackgroundHangThread()
|
||||
}
|
||||
|
||||
void
|
||||
BackgroundHangThread::ReportHang(TimeDuration aHangTime)
|
||||
BackgroundHangThread::ReportHang(PRIntervalTime aHangTime)
|
||||
{
|
||||
// Recovered from a hang; called on the monitor thread
|
||||
// mManager->mLock IS locked
|
||||
@ -504,7 +506,7 @@ BackgroundHangThread::ReportHang(TimeDuration aHangTime)
|
||||
#ifdef MOZ_GECKO_PROFILER
|
||||
if (profiler_is_active()) {
|
||||
TimeStamp endTime = TimeStamp::Now();
|
||||
TimeStamp startTime = endTime - aHangTime;
|
||||
TimeStamp startTime = endTime - TimeDuration::FromMilliseconds(aHangTime);
|
||||
profiler_add_marker_for_thread(
|
||||
mStackHelper.GetThreadId(),
|
||||
"BHR-detected hang",
|
||||
@ -531,20 +533,20 @@ BackgroundHangThread::ReportPermaHang()
|
||||
MOZ_ALWAYS_INLINE void
|
||||
BackgroundHangThread::Update()
|
||||
{
|
||||
TimeStamp now = mManager->mNow;
|
||||
PRIntervalTime intervalNow = mManager->mIntervalNow;
|
||||
if (mWaiting) {
|
||||
mLastActivity = now;
|
||||
mInterval = intervalNow;
|
||||
mWaiting = false;
|
||||
/* We have to wake up the manager thread because when all threads
|
||||
are waiting, the manager thread waits indefinitely as well. */
|
||||
mManager->Wakeup();
|
||||
} else {
|
||||
TimeDuration duration = now - mLastActivity;
|
||||
PRIntervalTime duration = intervalNow - mInterval;
|
||||
if (MOZ_UNLIKELY(duration >= mTimeout)) {
|
||||
/* Wake up the manager thread to tell it that a hang ended */
|
||||
mManager->Wakeup();
|
||||
}
|
||||
mLastActivity = now;
|
||||
mInterval = intervalNow;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,9 +13,9 @@
|
||||
namespace mozilla {
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHangDetails::GetDuration(double* aDuration)
|
||||
nsHangDetails::GetDuration(uint32_t* aDuration)
|
||||
{
|
||||
*aDuration = mDetails.duration().ToMilliseconds();
|
||||
*aDuration = mDetails.duration();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -69,4 +69,23 @@ private:
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
// We implement the ability to send the HangDetails object over IPC. We need to
|
||||
// do this rather than rely on StructuredClone of the objects created by the
|
||||
// XPCOM getters on nsHangDetails because we want to run BHR in the GPU process
|
||||
// which doesn't run any JS.
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
class ParamTraits<mozilla::HangDetails>
|
||||
{
|
||||
public:
|
||||
typedef mozilla::HangDetails paramType;
|
||||
static void Write(Message* aMsg, const paramType& aParam);
|
||||
static bool Read(const Message* aMsg,
|
||||
PickleIterator* aIter,
|
||||
paramType* aResult);
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif // mozilla_HangDetails_h
|
||||
|
@ -4,8 +4,6 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
using class mozilla::TimeDuration from "mozilla/TimeStamp.h";
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// The different kinds of hang entries which we're going to need to handle in
|
||||
@ -83,7 +81,7 @@ struct HangAnnotation
|
||||
// The information about an individual hang which is sent over IPC.
|
||||
struct HangDetails
|
||||
{
|
||||
TimeDuration duration;
|
||||
uint32_t duration;
|
||||
nsCString process;
|
||||
nsString remoteType;
|
||||
nsCString threadName;
|
||||
|
@ -21,9 +21,9 @@ class HangDetails;
|
||||
interface nsIHangDetails : nsISupports
|
||||
{
|
||||
/**
|
||||
* The detected duration of the hang in milliseconds.
|
||||
* The detected duration of the hang.
|
||||
*/
|
||||
readonly attribute double duration;
|
||||
readonly attribute uint32_t duration;
|
||||
|
||||
/**
|
||||
* The name of the thread which hung.
|
||||
|
@ -97,7 +97,7 @@ UpdateDriverSetupMacCommandLine(int& argc, char**& argv, bool restart)
|
||||
|
||||
// The length of this wait is arbitrary, but should be long enough that having
|
||||
// it expire means something is seriously wrong.
|
||||
rv = MonitorAutoLock(monitor).Wait(TimeDuration::FromSeconds(60));
|
||||
rv = MonitorAutoLock(monitor).Wait(PR_SecondsToInterval(60));
|
||||
if (NS_FAILED(rv)) {
|
||||
LOG(("Update driver timed out waiting for SetupMacCommandLine: %d\n", rv));
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ TEST(ThreadPool, Parallelism)
|
||||
if (!mDone) {
|
||||
// Wait for a reasonable timeout since we don't want to block gtests
|
||||
// forever should any regression happen.
|
||||
mon.Wait(TimeDuration::FromSeconds(300));
|
||||
mon.Wait(PR_SecondsToInterval(300));
|
||||
}
|
||||
EXPECT_TRUE(mDone);
|
||||
return NS_OK;
|
||||
|
@ -586,16 +586,8 @@ RecursiveMutex::AssertCurrentThreadIn()
|
||||
|
||||
//
|
||||
// Debug implementation of CondVar
|
||||
void
|
||||
CondVar::Wait()
|
||||
{
|
||||
// Forward to the timed version of CondVar::Wait to avoid code duplication.
|
||||
CVStatus status = Wait(TimeDuration::Forever());
|
||||
MOZ_ASSERT(status == CVStatus::NoTimeout);
|
||||
}
|
||||
|
||||
CVStatus
|
||||
CondVar::Wait(TimeDuration aDuration)
|
||||
nsresult
|
||||
CondVar::Wait(PRIntervalTime aInterval)
|
||||
{
|
||||
AssertCurrentThreadOwnsMutex();
|
||||
|
||||
@ -608,14 +600,18 @@ CondVar::Wait(TimeDuration aDuration)
|
||||
mLock->mOwningThread = nullptr;
|
||||
|
||||
// give up mutex until we're back from Wait()
|
||||
CVStatus status = mImpl.wait_for(*mLock, aDuration);
|
||||
if (aInterval == PR_INTERVAL_NO_TIMEOUT) {
|
||||
mImpl.wait(*mLock);
|
||||
} else {
|
||||
mImpl.wait_for(*mLock, TimeDuration::FromMilliseconds(double(aInterval)));
|
||||
}
|
||||
|
||||
// restore saved state
|
||||
mLock->SetAcquisitionState(savedAcquisitionState);
|
||||
mLock->mChainPrev = savedChainPrev;
|
||||
mLock->mOwningThread = savedOwningThread;
|
||||
|
||||
return status;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif // ifdef DEBUG
|
||||
|
@ -53,31 +53,27 @@ public:
|
||||
MOZ_COUNT_DTOR(CondVar);
|
||||
}
|
||||
|
||||
#ifndef DEBUG
|
||||
/**
|
||||
* Wait
|
||||
* @see prcvar.h
|
||||
**/
|
||||
#ifndef DEBUG
|
||||
void Wait()
|
||||
nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
|
||||
{
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
AUTO_PROFILER_THREAD_SLEEP;
|
||||
#endif //MOZILLA_INTERNAL_API
|
||||
mImpl.wait(*mLock);
|
||||
}
|
||||
|
||||
CVStatus Wait(TimeDuration aDuration)
|
||||
{
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
AUTO_PROFILER_THREAD_SLEEP;
|
||||
#endif //MOZILLA_INTERNAL_API
|
||||
return mImpl.wait_for(*mLock, aDuration);
|
||||
if (aInterval == PR_INTERVAL_NO_TIMEOUT) {
|
||||
mImpl.wait(*mLock);
|
||||
} else {
|
||||
mImpl.wait_for(*mLock, TimeDuration::FromMilliseconds(double(aInterval)));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
#else
|
||||
// NOTE: debug impl is in BlockingResourceBase.cpp
|
||||
void Wait();
|
||||
CVStatus Wait(TimeDuration aDuration);
|
||||
#endif
|
||||
nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT);
|
||||
#endif // ifndef DEBUG
|
||||
|
||||
/**
|
||||
* Notify
|
||||
@ -133,6 +129,7 @@ private:
|
||||
detail::ConditionVariableImpl mImpl;
|
||||
};
|
||||
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
|
||||
|
@ -262,11 +262,11 @@ ThreadMain(void*)
|
||||
waitCount = 0;
|
||||
}
|
||||
|
||||
TimeDuration timeout;
|
||||
PRIntervalTime timeout;
|
||||
if (gTimeout <= 0) {
|
||||
timeout = TimeDuration::Forever();
|
||||
timeout = PR_INTERVAL_NO_TIMEOUT;
|
||||
} else {
|
||||
timeout = TimeDuration::FromMilliseconds(gTimeout * 500);
|
||||
timeout = PR_MillisecondsToInterval(gTimeout * 500);
|
||||
}
|
||||
lock.Wait(timeout);
|
||||
}
|
||||
|
@ -35,8 +35,10 @@ public:
|
||||
void Lock() { mMutex.Lock(); }
|
||||
void Unlock() { mMutex.Unlock(); }
|
||||
|
||||
void Wait() { mCondVar.Wait(); }
|
||||
CVStatus Wait(TimeDuration aDuration) { return mCondVar.Wait(aDuration); }
|
||||
nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
|
||||
{
|
||||
return mCondVar.Wait(aInterval);
|
||||
}
|
||||
|
||||
nsresult Notify() { return mCondVar.Notify(); }
|
||||
nsresult NotifyAll() { return mCondVar.NotifyAll(); }
|
||||
@ -81,8 +83,10 @@ public:
|
||||
mMonitor->Unlock();
|
||||
}
|
||||
|
||||
void Wait() { mMonitor->Wait(); }
|
||||
CVStatus Wait(TimeDuration aDuration) { return mMonitor->Wait(aDuration); }
|
||||
nsresult Wait(PRIntervalTime aInterval = PR_INTERVAL_NO_TIMEOUT)
|
||||
{
|
||||
return mMonitor->Wait(aInterval);
|
||||
}
|
||||
|
||||
nsresult Notify() { return mMonitor->Notify(); }
|
||||
nsresult NotifyAll() { return mMonitor->NotifyAll(); }
|
||||
|
@ -443,7 +443,7 @@ SchedulerImpl::Switcher()
|
||||
}
|
||||
}
|
||||
|
||||
mShutdownCondVar.Wait(TimeDuration::FromMicroseconds(50));
|
||||
mShutdownCondVar.Wait(PR_MicrosecondsToInterval(50));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,7 +417,7 @@ TimerThread::Run()
|
||||
|
||||
while (!mShutdown) {
|
||||
// Have to use PRIntervalTime here, since PR_WaitCondVar takes it
|
||||
TimeDuration waitFor;
|
||||
PRIntervalTime waitFor;
|
||||
bool forceRunThisTimer = forceRunNextTimer;
|
||||
forceRunNextTimer = false;
|
||||
|
||||
@ -427,9 +427,9 @@ TimerThread::Run()
|
||||
if (ChaosMode::isActive(ChaosFeature::TimerScheduling)) {
|
||||
milliseconds = ChaosMode::randomUint32LessThan(200);
|
||||
}
|
||||
waitFor = TimeDuration::FromMilliseconds(milliseconds);
|
||||
waitFor = PR_MillisecondsToInterval(milliseconds);
|
||||
} else {
|
||||
waitFor = TimeDuration::Forever();
|
||||
waitFor = PR_INTERVAL_NO_TIMEOUT;
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
|
||||
RemoveLeadingCanceledTimersInternal();
|
||||
@ -516,20 +516,20 @@ TimerThread::Run()
|
||||
forceRunNextTimer = false;
|
||||
goto next; // round down; execute event now
|
||||
}
|
||||
waitFor = TimeDuration::FromMicroseconds(microseconds);
|
||||
if (waitFor.IsZero()) {
|
||||
// round up, wait the minimum time we can wait
|
||||
waitFor = TimeDuration::FromMicroseconds(1);
|
||||
waitFor = PR_MicrosecondsToInterval(
|
||||
static_cast<uint32_t>(microseconds)); // Floor is accurate enough.
|
||||
if (waitFor == 0) {
|
||||
waitFor = 1; // round up, wait the minimum time we can wait
|
||||
}
|
||||
}
|
||||
|
||||
if (MOZ_LOG_TEST(GetTimerLog(), LogLevel::Debug)) {
|
||||
if (waitFor == TimeDuration::Forever())
|
||||
if (waitFor == PR_INTERVAL_NO_TIMEOUT)
|
||||
MOZ_LOG(GetTimerLog(), LogLevel::Debug,
|
||||
("waiting forever\n"));
|
||||
("waiting for PR_INTERVAL_NO_TIMEOUT\n"));
|
||||
else
|
||||
MOZ_LOG(GetTimerLog(), LogLevel::Debug,
|
||||
("waiting for %f\n", waitFor.ToMilliseconds()));
|
||||
("waiting for %u\n", PR_IntervalToMilliseconds(waitFor)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ nsThreadPool::Run()
|
||||
bool shutdownThreadOnExit = false;
|
||||
bool exitThread = false;
|
||||
bool wasIdle = false;
|
||||
TimeStamp idleSince;
|
||||
PRIntervalTime idleSince;
|
||||
|
||||
nsCOMPtr<nsIThreadPoolListener> listener;
|
||||
{
|
||||
@ -182,8 +182,8 @@ nsThreadPool::Run()
|
||||
|
||||
event = mEvents.GetEvent(nullptr, lock);
|
||||
if (!event) {
|
||||
TimeStamp now = TimeStamp::Now();
|
||||
TimeDuration timeout = TimeDuration::FromMilliseconds(mIdleThreadTimeout);
|
||||
PRIntervalTime now = PR_IntervalNow();
|
||||
PRIntervalTime timeout = PR_MillisecondsToInterval(mIdleThreadTimeout);
|
||||
|
||||
// If we are shutting down, then don't keep any idle threads
|
||||
if (mShutdown) {
|
||||
@ -213,9 +213,8 @@ nsThreadPool::Run()
|
||||
}
|
||||
shutdownThreadOnExit = mThreads.RemoveObject(current);
|
||||
} else {
|
||||
TimeDuration delta = timeout - (now - idleSince);
|
||||
LOG(("THRD-P(%p) %s waiting [%f]\n", this, mName.BeginReading(),
|
||||
delta.ToMilliseconds()));
|
||||
PRIntervalTime delta = timeout - (now - idleSince);
|
||||
LOG(("THRD-P(%p) %s waiting [%d]\n", this, mName.BeginReading(), delta));
|
||||
mEventsAvailable.Wait(delta);
|
||||
LOG(("THRD-P(%p) done waiting\n", this));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user