From a1aaf949a5d3b639f03dd7e33ffe1f0849b7f8df Mon Sep 17 00:00:00 2001 From: Matthijs Date: Thu, 25 Jun 2015 22:53:58 +0200 Subject: [PATCH] Optimizations for Windows - Set opt_lg_chunk based on run-time OS setting - Verify LG_PAGE is compatible with run-time OS setting - When targeting Windows Vista or newer, use SRWLOCK instead of CRITICAL_SECTION - When targeting Windows Vista or newer, statically initialize init_lock --- include/jemalloc/internal/mutex.h | 12 ++++++++++++ src/chunk.c | 17 ++++++++++++++++- src/jemalloc.c | 5 ++++- src/mutex.c | 4 ++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/include/jemalloc/internal/mutex.h b/include/jemalloc/internal/mutex.h index 8a03d825..f051f291 100644 --- a/include/jemalloc/internal/mutex.h +++ b/include/jemalloc/internal/mutex.h @@ -26,7 +26,11 @@ typedef struct malloc_mutex_s malloc_mutex_t; struct malloc_mutex_s { #ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + SRWLOCK lock; +# else CRITICAL_SECTION lock; +# endif #elif (defined(JEMALLOC_OSSPIN)) OSSpinLock lock; #elif (defined(JEMALLOC_MUTEX_INIT_CB)) @@ -70,7 +74,11 @@ malloc_mutex_lock(malloc_mutex_t *mutex) if (isthreaded) { #ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + AcquireSRWLockExclusive(&mutex->lock); +# else EnterCriticalSection(&mutex->lock); +# endif #elif (defined(JEMALLOC_OSSPIN)) OSSpinLockLock(&mutex->lock); #else @@ -85,7 +93,11 @@ malloc_mutex_unlock(malloc_mutex_t *mutex) if (isthreaded) { #ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + ReleaseSRWLockExclusive(&mutex->lock); +# else LeaveCriticalSection(&mutex->lock); +# endif #elif (defined(JEMALLOC_OSSPIN)) OSSpinLockUnlock(&mutex->lock); #else diff --git a/src/chunk.c b/src/chunk.c index 12799659..b600aba0 100644 --- a/src/chunk.c +++ b/src/chunk.c @@ -5,7 +5,7 @@ /* Data. */ const char *opt_dss = DSS_DEFAULT; -size_t opt_lg_chunk = LG_CHUNK_DEFAULT; +size_t opt_lg_chunk = 0; /* Used exclusively for gdump triggering. */ static size_t curchunks; @@ -535,6 +535,21 @@ chunks_rtree_node_alloc(size_t nelms) bool chunk_boot(void) { +#ifdef _WIN32 + SYSTEM_INFO info; + GetSystemInfo(&info); + + /* Verify actual page size is equal to or an integral multiple of configured page size */ + if (info.dwPageSize & ((1U << LG_PAGE) - 1)) + return (true); + + /* Configure chunksize (if not set) to match granularity (usually 64K), so pages_map will always take fast path */ + if (!opt_lg_chunk) + opt_lg_chunk = ffs((int)info.dwAllocationGranularity) - 1; +#else + if (!opt_lg_chunk) + opt_lg_chunk = LG_CHUNK_DEFAULT; +#endif /* Set variables according to the value of opt_lg_chunk. */ chunksize = (ZU(1) << opt_lg_chunk); diff --git a/src/jemalloc.c b/src/jemalloc.c index 01cb394a..43c4c81e 100644 --- a/src/jemalloc.c +++ b/src/jemalloc.c @@ -175,6 +175,9 @@ static bool malloc_initializer = NO_INITIALIZER; /* Used to avoid initialization races. */ #ifdef _WIN32 +#if _WIN32_WINNT >= 0x0600 +static malloc_mutex_t init_lock = SRWLOCK_INIT; +#else static malloc_mutex_t init_lock; JEMALLOC_ATTR(constructor) @@ -190,7 +193,7 @@ _init_init_lock(void) JEMALLOC_SECTION(".CRT$XCU") JEMALLOC_ATTR(used) static const void (WINAPI *init_init_lock)(void) = _init_init_lock; #endif - +#endif #else static malloc_mutex_t init_lock = MALLOC_MUTEX_INITIALIZER; #endif diff --git a/src/mutex.c b/src/mutex.c index d86887ee..2d47af97 100644 --- a/src/mutex.c +++ b/src/mutex.c @@ -73,9 +73,13 @@ malloc_mutex_init(malloc_mutex_t *mutex) { #ifdef _WIN32 +# if _WIN32_WINNT >= 0x0600 + InitializeSRWLock(&mutex->lock); +# else if (!InitializeCriticalSectionAndSpinCount(&mutex->lock, _CRT_SPINCOUNT)) return (true); +# endif #elif (defined(JEMALLOC_OSSPIN)) mutex->lock = 0; #elif (defined(JEMALLOC_MUTEX_INIT_CB))