summaryrefslogtreecommitdiff
path: root/pr/src/md/windows/w95cv.c
diff options
context:
space:
mode:
authorwtc%google.com <devnull@localhost>2013-02-10 19:14:25 +0000
committerwtc%google.com <devnull@localhost>2013-02-10 19:14:25 +0000
commit8eb9e834b963a2dc0e2c070df02d98b5e874ca7e (patch)
treeb76a1c4542fb7f9c8feba3978086e9d705c4c5e0 /pr/src/md/windows/w95cv.c
parentffb6dd9deddc608631fb008abb8ffea22bc68c58 (diff)
downloadnspr-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.c54
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;
}