зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1221160 - fix AutoTraceLogLock deadlock on Windows; r=froydnj
From e3a1e57c0c8be8214a12e31c6e4950a676efd9bc Mon Sep 17 00:00:00 2001 MozReview-Commit-ID: JrPiE7eixpy --HG-- extra : rebase_source : 7f322a0c95c46c0bd1721f982fab8ab421866d70 extra : source : 883ed100b755b9a528104a62ed631beaff6c8cf2
This commit is contained in:
Родитель
6a82950698
Коммит
a54ea93315
|
@ -61,17 +61,24 @@
|
||||||
// only held for a very short time, and gets grabbed at a very high frequency
|
// only held for a very short time, and gets grabbed at a very high frequency
|
||||||
// (~100000 times per second). On Mac, the overhead of using a regular lock
|
// (~100000 times per second). On Mac, the overhead of using a regular lock
|
||||||
// is very high, see bug 1137963.
|
// is very high, see bug 1137963.
|
||||||
static mozilla::Atomic<bool, mozilla::ReleaseAcquire> gTraceLogLocked;
|
static mozilla::Atomic<uintptr_t, mozilla::ReleaseAcquire> gTraceLogLocked;
|
||||||
|
|
||||||
struct MOZ_STACK_CLASS AutoTraceLogLock final
|
struct MOZ_STACK_CLASS AutoTraceLogLock final
|
||||||
{
|
{
|
||||||
|
bool doRelease;
|
||||||
AutoTraceLogLock()
|
AutoTraceLogLock()
|
||||||
|
: doRelease(true)
|
||||||
{
|
{
|
||||||
while (!gTraceLogLocked.compareExchange(false, true)) {
|
uintptr_t currentThread = reinterpret_cast<uintptr_t>(PR_GetCurrentThread());
|
||||||
PR_Sleep(PR_INTERVAL_NO_WAIT); /* yield */
|
if (gTraceLogLocked == currentThread) {
|
||||||
|
doRelease = false;
|
||||||
|
} else {
|
||||||
|
while (!gTraceLogLocked.compareExchange(0, currentThread)) {
|
||||||
|
PR_Sleep(PR_INTERVAL_NO_WAIT); /* yield */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
~AutoTraceLogLock() { gTraceLogLocked = false; }
|
~AutoTraceLogLock() { if (doRelease) gTraceLogLocked = 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static PLHashTable* gBloatView;
|
static PLHashTable* gBloatView;
|
||||||
|
@ -1119,14 +1126,14 @@ NS_LogAddRef(void* aPtr, nsrefcnt aRefcnt,
|
||||||
|
|
||||||
bool loggingThisObject = (!gObjectsToLog || LogThisObj(serialno));
|
bool loggingThisObject = (!gObjectsToLog || LogThisObj(serialno));
|
||||||
if (aRefcnt == 1 && gAllocLog && loggingThisType && loggingThisObject) {
|
if (aRefcnt == 1 && gAllocLog && loggingThisType && loggingThisObject) {
|
||||||
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Create\n", aClass, aPtr, serialno);
|
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Create [thread %p]\n", aClass, aPtr, serialno, PR_GetCurrentThread());
|
||||||
nsTraceRefcnt::WalkTheStackCached(gAllocLog);
|
nsTraceRefcnt::WalkTheStackCached(gAllocLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gRefcntsLog && loggingThisType && loggingThisObject) {
|
if (gRefcntsLog && loggingThisType && loggingThisObject) {
|
||||||
// Can't use MOZ_LOG(), b/c it truncates the line
|
// Can't use MOZ_LOG(), b/c it truncates the line
|
||||||
fprintf(gRefcntsLog, "\n<%s> %p %" PRIuPTR " AddRef %" PRIuPTR "\n",
|
fprintf(gRefcntsLog, "\n<%s> %p %" PRIuPTR " AddRef %" PRIuPTR " [thread %p]\n",
|
||||||
aClass, aPtr, serialno, aRefcnt);
|
aClass, aPtr, serialno, aRefcnt, PR_GetCurrentThread());
|
||||||
nsTraceRefcnt::WalkTheStackCached(gRefcntsLog);
|
nsTraceRefcnt::WalkTheStackCached(gRefcntsLog);
|
||||||
fflush(gRefcntsLog);
|
fflush(gRefcntsLog);
|
||||||
}
|
}
|
||||||
|
@ -1173,8 +1180,8 @@ NS_LogRelease(void* aPtr, nsrefcnt aRefcnt, const char* aClass)
|
||||||
if (gRefcntsLog && loggingThisType && loggingThisObject) {
|
if (gRefcntsLog && loggingThisType && loggingThisObject) {
|
||||||
// Can't use MOZ_LOG(), b/c it truncates the line
|
// Can't use MOZ_LOG(), b/c it truncates the line
|
||||||
fprintf(gRefcntsLog,
|
fprintf(gRefcntsLog,
|
||||||
"\n<%s> %p %" PRIuPTR " Release %" PRIuPTR "\n",
|
"\n<%s> %p %" PRIuPTR " Release %" PRIuPTR " [thread %p]\n",
|
||||||
aClass, aPtr, serialno, aRefcnt);
|
aClass, aPtr, serialno, aRefcnt, PR_GetCurrentThread());
|
||||||
nsTraceRefcnt::WalkTheStackCached(gRefcntsLog);
|
nsTraceRefcnt::WalkTheStackCached(gRefcntsLog);
|
||||||
fflush(gRefcntsLog);
|
fflush(gRefcntsLog);
|
||||||
}
|
}
|
||||||
|
@ -1183,7 +1190,7 @@ NS_LogRelease(void* aPtr, nsrefcnt aRefcnt, const char* aClass)
|
||||||
// yet we still want to see deletion information:
|
// yet we still want to see deletion information:
|
||||||
|
|
||||||
if (aRefcnt == 0 && gAllocLog && loggingThisType && loggingThisObject) {
|
if (aRefcnt == 0 && gAllocLog && loggingThisType && loggingThisObject) {
|
||||||
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Destroy\n", aClass, aPtr, serialno);
|
fprintf(gAllocLog, "\n<%s> %p %" PRIdPTR " Destroy [thread %p]\n", aClass, aPtr, serialno, PR_GetCurrentThread());
|
||||||
nsTraceRefcnt::WalkTheStackCached(gAllocLog);
|
nsTraceRefcnt::WalkTheStackCached(gAllocLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче