From: Jeffrey Altman Date: Thu, 4 Aug 2011 21:15:16 +0000 (-0400) Subject: Windows: LockOrderValidation memory usage optimization X-Git-Tag: openafs-devel-1_7_1~195 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=17e50a4b98de057a699681261ba126a5ac12a0cc Windows: LockOrderValidation memory usage optimization Instead of using malloc() and free() to allocation lock reference structures, cache allocated objects in a free list. This reduces memory fragmentation. Change-Id: Idffe82282c77202d0fc3a9be9123c3b7384ecd63 Reviewed-on: http://gerrit.openafs.org/5159 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/client_osi/osibasel.c b/src/WINNT/client_osi/osibasel.c index d69aebf..40d1207 100644 --- a/src/WINNT/client_osi/osibasel.c +++ b/src/WINNT/client_osi/osibasel.c @@ -26,6 +26,9 @@ static long atomicIndexCounter = 0; static DWORD tls_LockRefH = 0; static DWORD tls_LockRefT = 0; static BOOLEAN lockOrderValidation = 0; +static osi_lock_ref_t * lock_ref_FreeListp = NULL; +static osi_lock_ref_t * lock_ref_FreeListEndp = NULL; +CRITICAL_SECTION lock_ref_CS; void osi_BaseInit(void) { @@ -39,16 +42,32 @@ void osi_BaseInit(void) if ((tls_LockRefT = TlsAlloc()) == TLS_OUT_OF_INDEXES) osi_panic("TlsAlloc(tls_LockRefT) failure", __FILE__, __LINE__); + + InitializeCriticalSection(&lock_ref_CS); } -void osi_SetLockOrderValidation(int on) +void +osi_SetLockOrderValidation(int on) { lockOrderValidation = (BOOLEAN)on; } -osi_lock_ref_t *lock_GetLockRef(void * lockp, char type) +static osi_lock_ref_t * +lock_GetLockRef(void * lockp, char type) { - osi_lock_ref_t * lockRefp = (osi_lock_ref_t *)malloc(sizeof(osi_lock_ref_t)); + osi_lock_ref_t * lockRefp = NULL; + + EnterCriticalSection(&lock_ref_CS); + if (lock_ref_FreeListp) { + lockRefp = lock_ref_FreeListp; + osi_QRemoveHT( (osi_queue_t **) &lock_ref_FreeListp, + (osi_queue_t **) &lock_ref_FreeListEndp, + &lockRefp->q); + } + LeaveCriticalSection(&lock_ref_CS); + + if (lockRefp == NULL) + lockRefp = (osi_lock_ref_t *)malloc(sizeof(osi_lock_ref_t)); memset(lockRefp, 0, sizeof(osi_lock_ref_t)); lockRefp->type = type; @@ -66,6 +85,16 @@ osi_lock_ref_t *lock_GetLockRef(void * lockp, char type) return lockRefp; } +static void +lock_FreeLockRef(osi_lock_ref_t * lockRefp) +{ + EnterCriticalSection(&lock_ref_CS); + osi_QAddH( (osi_queue_t **) &lock_ref_FreeListp, + (osi_queue_t **) &lock_ref_FreeListEndp, + &lockRefp->q); + LeaveCriticalSection(&lock_ref_CS); +} + void lock_VerifyOrderRW(osi_queue_t *lockRefH, osi_queue_t *lockRefT, osi_rwlock_t *lockp) { char msg[512]; @@ -237,7 +266,7 @@ void lock_ReleaseRead(osi_rwlock_t *lockp) for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) { if (lockRefp->type == OSI_LOCK_RW && lockRefp->rw == lockp) { osi_QRemoveHT(&lockRefH, &lockRefT, &lockRefp->q); - free(lockRefp); + lock_FreeLockRef(lockRefp); found = 1; break; } @@ -285,7 +314,7 @@ void lock_ReleaseWrite(osi_rwlock_t *lockp) for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) { if (lockRefp->type == OSI_LOCK_RW && lockRefp->rw == lockp) { osi_QRemoveHT(&lockRefH, &lockRefT, &lockRefp->q); - free(lockRefp); + lock_FreeLockRef(lockRefp); found = 1; break; } @@ -448,7 +477,7 @@ void lock_ReleaseMutex(struct osi_mutex *lockp) for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) { if (lockRefp->type == OSI_LOCK_MUTEX && lockRefp->mx == lockp) { osi_QRemoveHT(&lockRefH, &lockRefT, &lockRefp->q); - free(lockRefp); + lock_FreeLockRef(lockRefp); found = 1; break; } @@ -654,7 +683,7 @@ void osi_SleepR(LONG_PTR sleepVal, struct osi_rwlock *lockp) for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) { if (lockRefp->type == OSI_LOCK_RW && lockRefp->rw == lockp) { osi_QRemoveHT(&lockRefH, &lockRefT, &lockRefp->q); - free(lockRefp); + lock_FreeLockRef(lockRefp); break; } } @@ -700,7 +729,7 @@ void osi_SleepW(LONG_PTR sleepVal, struct osi_rwlock *lockp) for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) { if (lockRefp->type == OSI_LOCK_RW && lockRefp->rw == lockp) { osi_QRemoveHT(&lockRefH, &lockRefT, &lockRefp->q); - free(lockRefp); + lock_FreeLockRef(lockRefp); break; } } @@ -744,7 +773,7 @@ void osi_SleepM(LONG_PTR sleepVal, struct osi_mutex *lockp) for (lockRefp = (osi_lock_ref_t *)lockRefH ; lockRefp; lockRefp = (osi_lock_ref_t *)osi_QNext(&lockRefp->q)) { if (lockRefp->type == OSI_LOCK_MUTEX && lockRefp->mx == lockp) { osi_QRemoveHT(&lockRefH, &lockRefT, &lockRefp->q); - free(lockRefp); + lock_FreeLockRef(lockRefp); break; } }