diff options
author | wtc%google.com <devnull@localhost> | 2013-02-10 19:14:25 +0000 |
---|---|---|
committer | wtc%google.com <devnull@localhost> | 2013-02-10 19:14:25 +0000 |
commit | 8eb9e834b963a2dc0e2c070df02d98b5e874ca7e (patch) | |
tree | b76a1c4542fb7f9c8feba3978086e9d705c4c5e0 /pr/src/md/windows/w95cv.c | |
parent | ffb6dd9deddc608631fb008abb8ffea22bc68c58 (diff) | |
download | nspr-hg-8eb9e834b963a2dc0e2c070df02d98b5e874ca7e.tar.gz |
Bug 812085: Initialize Windows CRITICAL_SECTIONs without debug info and
with nonzero spin count (1500). The patch is contributed by Chris Peterson
<cpeterson@mozilla.com>. r=wtc.
Modified Files:
pr/include/md/_win95.h pr/src/md/windows/w95cv.c
Diffstat (limited to 'pr/src/md/windows/w95cv.c')
-rw-r--r-- | pr/src/md/windows/w95cv.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/pr/src/md/windows/w95cv.c b/pr/src/md/windows/w95cv.c index afff1b70..27b34e69 100644 --- a/pr/src/md/windows/w95cv.c +++ b/pr/src/md/windows/w95cv.c @@ -304,6 +304,59 @@ void _PR_MD_NOTIFYALL_CV(_MDCVar *cv, _MDLock *lock) return; } +typedef BOOL (WINAPI *INITIALIZECRITICALSECTIONEX)( + CRITICAL_SECTION *lpCriticalSection, + DWORD dwSpinCount, + DWORD Flags); + +static INITIALIZECRITICALSECTIONEX sInitializeCriticalSectionEx; + +void _PR_MD_INIT_LOCKS(void) +{ + /* + * Starting with Windows Vista, every CRITICAL_SECTION allocates an extra + * RTL_CRITICAL_SECTION_DEBUG object. Unfortunately, this debug object is + * not reclaimed by DeleteCriticalSection(), causing an apparent memory + * leak. This is a debugging "feature", not a bug. If we are running on + * Vista or later, use InitializeCriticalSectionEx() to allocate + * CRITICAL_SECTIONs without debug objects. + */ + HMODULE hKernel32 = GetModuleHandle("kernel32.dll"); + PR_ASSERT(hKernel32); + PR_ASSERT(!sInitializeCriticalSectionEx); + sInitializeCriticalSectionEx = (INITIALIZECRITICALSECTIONEX) + GetProcAddress(hKernel32, "InitializeCriticalSectionEx"); +} + +/* + * By default, CRITICAL_SECTIONs are initialized with a spin count of 0. + * Joe Duffy's "Concurrent Programming on Windows" book suggests 1500 is + * a "reasonable starting point". On single-processor systems, the spin + * count is ignored and the critical section spin count is set to 0. + */ +#define LOCK_SPIN_COUNT 1500 + +PRStatus _PR_MD_NEW_LOCK(_MDLock *lock) +{ + CRITICAL_SECTION *cs = &lock->mutex; + BOOL ok; + + if (sInitializeCriticalSectionEx) { + ok = sInitializeCriticalSectionEx(cs, LOCK_SPIN_COUNT, + CRITICAL_SECTION_NO_DEBUG_INFO); + } else { + ok = InitializeCriticalSectionAndSpinCount(cs, LOCK_SPIN_COUNT); + } + if (!ok) { + _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); + return PR_FAILURE; + } + + lock->notified.length = 0; + lock->notified.link = NULL; + return PR_SUCCESS; +} + void _PR_MD_UNLOCK(_MDLock *lock) { if (0 != lock->notified.length) { @@ -311,5 +364,4 @@ void _PR_MD_UNLOCK(_MDLock *lock) } else { LeaveCriticalSection(&lock->mutex); } - return; } |