From 3a58934eb2abf539ed229e97a5c9dd0a1dac9164 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Wed, 7 Aug 2013 17:10:43 +0200 Subject: [PATCH] libwinpr-utils: Use criticalsection with spincount Use InitializeCriticalSectionAndSpinCount instead of IntializeCriticalSection. Using spin counts for critical sections of short duration enables the calling thread to avoid the wait operation in most situations which can dramatically improve the overall performance on multiprocessor systems. On Linux this change has no effect because the new winpr critical section implementation does not use the SpinCount field under Linux because the NPTL synchronization primitives are implemented using the extremely performant futex system calls which have this magic already built in. However, on Mac OS X this change improved the overall performance of the multithreaded RemoteFX decoder by 25 percent. I've used a SpinCount of 4000 which avoided 99 percent of the wait calls. This value is also used by Microsoft's heap manager for its per-heap critical sections. Note: This change requires pull request #1397 to be merged. --- winpr/libwinpr/utils/collections/ArrayList.c | 2 +- winpr/libwinpr/utils/collections/BufferPool.c | 2 +- winpr/libwinpr/utils/collections/CountdownEvent.c | 2 +- winpr/libwinpr/utils/collections/MessageQueue.c | 2 +- winpr/libwinpr/utils/collections/ObjectPool.c | 2 +- winpr/libwinpr/utils/collections/PubSub.c | 2 +- winpr/libwinpr/utils/collections/Queue.c | 2 +- winpr/libwinpr/utils/collections/Reference.c | 2 +- winpr/libwinpr/utils/collections/Stack.c | 2 +- winpr/libwinpr/utils/collections/StreamPool.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/winpr/libwinpr/utils/collections/ArrayList.c b/winpr/libwinpr/utils/collections/ArrayList.c index 40fec723d..a337e2169 100644 --- a/winpr/libwinpr/utils/collections/ArrayList.c +++ b/winpr/libwinpr/utils/collections/ArrayList.c @@ -390,7 +390,7 @@ wArrayList* ArrayList_New(BOOL synchronized) arrayList->array = (void**) malloc(sizeof(void*) * arrayList->capacity); - InitializeCriticalSection(&arrayList->lock); + InitializeCriticalSectionAndSpinCount(&arrayList->lock, 4000); ZeroMemory(&arrayList->object, sizeof(wObject)); } diff --git a/winpr/libwinpr/utils/collections/BufferPool.c b/winpr/libwinpr/utils/collections/BufferPool.c index 3a8c317e9..b4f22b712 100644 --- a/winpr/libwinpr/utils/collections/BufferPool.c +++ b/winpr/libwinpr/utils/collections/BufferPool.c @@ -134,7 +134,7 @@ wBufferPool* BufferPool_New(BOOL synchronized, int fixedSize, DWORD alignment) pool->synchronized = synchronized; if (pool->synchronized) - InitializeCriticalSection(&pool->lock); + InitializeCriticalSectionAndSpinCount(&pool->lock, 4000); if (!pool->fixedSize) { diff --git a/winpr/libwinpr/utils/collections/CountdownEvent.c b/winpr/libwinpr/utils/collections/CountdownEvent.c index 0f11bb2ec..ea50f4219 100644 --- a/winpr/libwinpr/utils/collections/CountdownEvent.c +++ b/winpr/libwinpr/utils/collections/CountdownEvent.c @@ -158,7 +158,7 @@ wCountdownEvent* CountdownEvent_New(DWORD initialCount) { countdown->count = initialCount; countdown->initialCount = initialCount; - InitializeCriticalSection(&countdown->lock); + InitializeCriticalSectionAndSpinCount(&countdown->lock, 4000); countdown->event = CreateEvent(NULL, TRUE, FALSE, NULL); if (countdown->count == 0) diff --git a/winpr/libwinpr/utils/collections/MessageQueue.c b/winpr/libwinpr/utils/collections/MessageQueue.c index 871316ab0..e7b8a5e84 100644 --- a/winpr/libwinpr/utils/collections/MessageQueue.c +++ b/winpr/libwinpr/utils/collections/MessageQueue.c @@ -194,7 +194,7 @@ wMessageQueue* MessageQueue_New() queue->array = (wMessage*) malloc(sizeof(wMessage) * queue->capacity); ZeroMemory(queue->array, sizeof(wMessage) * queue->capacity); - InitializeCriticalSection(&queue->lock); + InitializeCriticalSectionAndSpinCount(&queue->lock, 4000); queue->event = CreateEvent(NULL, TRUE, FALSE, NULL); } diff --git a/winpr/libwinpr/utils/collections/ObjectPool.c b/winpr/libwinpr/utils/collections/ObjectPool.c index 488559085..c0e36266f 100644 --- a/winpr/libwinpr/utils/collections/ObjectPool.c +++ b/winpr/libwinpr/utils/collections/ObjectPool.c @@ -119,7 +119,7 @@ wObjectPool* ObjectPool_New(BOOL synchronized) pool->synchronized = synchronized; if (pool->synchronized) - InitializeCriticalSection(&pool->lock); + InitializeCriticalSectionAndSpinCount(&pool->lock, 4000); pool->size = 0; pool->capacity = 32; diff --git a/winpr/libwinpr/utils/collections/PubSub.c b/winpr/libwinpr/utils/collections/PubSub.c index 26c89968a..abd29098c 100644 --- a/winpr/libwinpr/utils/collections/PubSub.c +++ b/winpr/libwinpr/utils/collections/PubSub.c @@ -202,7 +202,7 @@ wPubSub* PubSub_New(BOOL synchronized) pubSub->synchronized = synchronized; if (pubSub->synchronized) - InitializeCriticalSection(&pubSub->lock); + InitializeCriticalSectionAndSpinCount(&pubSub->lock, 4000); pubSub->count = 0; pubSub->size = 64; diff --git a/winpr/libwinpr/utils/collections/Queue.c b/winpr/libwinpr/utils/collections/Queue.c index 95210649d..7a729622e 100644 --- a/winpr/libwinpr/utils/collections/Queue.c +++ b/winpr/libwinpr/utils/collections/Queue.c @@ -243,7 +243,7 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor) queue->array = (void**) malloc(sizeof(void*) * queue->capacity); ZeroMemory(queue->array, sizeof(void*) * queue->capacity); - InitializeCriticalSection(&queue->lock); + InitializeCriticalSectionAndSpinCount(&queue->lock, 4000); queue->event = CreateEvent(NULL, TRUE, FALSE, NULL); ZeroMemory(&queue->object, sizeof(wObject)); diff --git a/winpr/libwinpr/utils/collections/Reference.c b/winpr/libwinpr/utils/collections/Reference.c index 6c32ffeac..171123661 100644 --- a/winpr/libwinpr/utils/collections/Reference.c +++ b/winpr/libwinpr/utils/collections/Reference.c @@ -154,7 +154,7 @@ wReferenceTable* ReferenceTable_New(BOOL synchronized, void* context, REFERENCE_ ZeroMemory(referenceTable->array, sizeof(wReference) * referenceTable->size); referenceTable->synchronized = synchronized; - InitializeCriticalSection(&referenceTable->lock); + InitializeCriticalSectionAndSpinCount(&referenceTable->lock, 4000); } return referenceTable; diff --git a/winpr/libwinpr/utils/collections/Stack.c b/winpr/libwinpr/utils/collections/Stack.c index a0d063eee..5ddb18088 100644 --- a/winpr/libwinpr/utils/collections/Stack.c +++ b/winpr/libwinpr/utils/collections/Stack.c @@ -153,7 +153,7 @@ wStack* Stack_New(BOOL synchronized) stack->synchronized = synchronized; if (stack->synchronized) - InitializeCriticalSection(&stack->lock); + InitializeCriticalSectionAndSpinCount(&stack->lock, 4000); stack->size = 0; stack->capacity = 32; diff --git a/winpr/libwinpr/utils/collections/StreamPool.c b/winpr/libwinpr/utils/collections/StreamPool.c index 418681c61..4df2fe8b3 100644 --- a/winpr/libwinpr/utils/collections/StreamPool.c +++ b/winpr/libwinpr/utils/collections/StreamPool.c @@ -323,7 +323,7 @@ wStreamPool* StreamPool_New(BOOL synchronized, size_t defaultSize) pool->synchronized = synchronized; pool->defaultSize = defaultSize; - InitializeCriticalSection(&pool->lock); + InitializeCriticalSectionAndSpinCount(&pool->lock, 4000); pool->aSize = 0; pool->aCapacity = 32;