You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by da...@apache.org on 2007/07/12 21:29:44 UTC
svn commit: r555730 - in /apr/apr/trunk:
include/arch/win32/apr_arch_thread_cond.h locks/win32/thread_cond.c
test/testcond.c
Author: davi
Date: Thu Jul 12 12:29:43 2007
New Revision: 555730
URL: http://svn.apache.org/viewvc?view=rev&rev=555730
Log:
Improve WIN32 condition variables fairness by using a generation count. The count
assures that one thread won't steal wakeups from other threads in the queue.
Modified:
apr/apr/trunk/include/arch/win32/apr_arch_thread_cond.h
apr/apr/trunk/locks/win32/thread_cond.c
apr/apr/trunk/test/testcond.c
Modified: apr/apr/trunk/include/arch/win32/apr_arch_thread_cond.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/arch/win32/apr_arch_thread_cond.h?view=diff&rev=555730&r1=555729&r2=555730
==============================================================================
--- apr/apr/trunk/include/arch/win32/apr_arch_thread_cond.h (original)
+++ apr/apr/trunk/include/arch/win32/apr_arch_thread_cond.h Thu Jul 12 12:29:43 2007
@@ -25,6 +25,7 @@
CRITICAL_SECTION csection;
unsigned long num_waiting;
unsigned long num_wake;
+ unsigned long generation;
};
#endif /* THREAD_COND_H */
Modified: apr/apr/trunk/locks/win32/thread_cond.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/locks/win32/thread_cond.c?view=diff&rev=555730&r1=555729&r2=555730
==============================================================================
--- apr/apr/trunk/locks/win32/thread_cond.c (original)
+++ apr/apr/trunk/locks/win32/thread_cond.c Thu Jul 12 12:29:43 2007
@@ -67,27 +67,43 @@
{
DWORD res;
apr_status_t rv;
+ unsigned int wake = 0;
+ unsigned long generation;
EnterCriticalSection(&cond->csection);
cond->num_waiting++;
+ generation = cond->generation;
LeaveCriticalSection(&cond->csection);
apr_thread_mutex_unlock(mutex);
do {
res = WaitForSingleObject(cond->semaphore, timeout_ms);
+
EnterCriticalSection(&cond->csection);
+
if (cond->num_wake) {
- cond->num_wake--;
- rv = APR_SUCCESS;
- break;
+ if (cond->generation != generation) {
+ cond->num_wake--;
+ cond->num_waiting--;
+ rv = APR_SUCCESS;
+ break;
+ } else {
+ wake = 1;
+ }
}
else if (res != WAIT_OBJECT_0) {
cond->num_waiting--;
rv = APR_TIMEUP;
break;
}
+
LeaveCriticalSection(&cond->csection);
+
+ if (wake) {
+ wake = 0;
+ ReleaseSemaphore(cond->semaphore, 1, NULL);
+ }
} while (1);
LeaveCriticalSection(&cond->csection);
@@ -116,10 +132,10 @@
unsigned int wake = 0;
EnterCriticalSection(&cond->csection);
- if (cond->num_waiting) {
+ if (cond->num_waiting > cond->num_wake) {
wake = 1;
cond->num_wake++;
- cond->num_waiting--;
+ cond->generation++;
}
LeaveCriticalSection(&cond->csection);
@@ -135,9 +151,10 @@
unsigned long num_wake = 0;
EnterCriticalSection(&cond->csection);
- if (cond->num_waiting) {
- cond->num_wake += num_wake = cond->num_waiting;
- cond->num_waiting = 0;
+ if (cond->num_waiting > cond->num_wake) {
+ num_wake = cond->num_waiting - cond->num_wake;
+ cond->num_wake = cond->num_waiting;
+ cond->generation++;
}
LeaveCriticalSection(&cond->csection);
Modified: apr/apr/trunk/test/testcond.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/test/testcond.c?view=diff&rev=555730&r1=555729&r2=555730
==============================================================================
--- apr/apr/trunk/test/testcond.c (original)
+++ apr/apr/trunk/test/testcond.c Thu Jul 12 12:29:43 2007
@@ -511,20 +511,19 @@
rv = apr_thread_mutex_lock(box->mutex);
ABTS_SUCCESS(rv);
+ if (state == TOSS)
+ state = PING;
+
do {
+ rv = apr_thread_cond_signal(box->cond);
+ ABTS_SUCCESS(rv);
+
state = PONG;
- rv = apr_thread_cond_signal(box->cond);
+ rv = apr_thread_cond_wait(box->cond, box->mutex);
ABTS_SUCCESS(rv);
- do {
- rv = apr_thread_cond_wait(box->cond, box->mutex);
- ABTS_SUCCESS(rv);
- if (state == OVER) {
- break;
- }
- ABTS_INT_EQUAL(tc, 1, (state == PING));
- } while (state == PONG);
+ ABTS_TRUE(tc, state == PING || state == OVER);
} while (state != OVER);
rv = apr_thread_mutex_unlock(box->mutex);
@@ -542,20 +541,19 @@
rv = apr_thread_mutex_lock(box->mutex);
ABTS_SUCCESS(rv);
+ if (state == TOSS)
+ state = PONG;
+
do {
+ rv = apr_thread_cond_signal(box->cond);
+ ABTS_SUCCESS(rv);
+
state = PING;
- rv = apr_thread_cond_signal(box->cond);
+ rv = apr_thread_cond_wait(box->cond, box->mutex);
ABTS_SUCCESS(rv);
- do {
- rv = apr_thread_cond_wait(box->cond, box->mutex);
- ABTS_SUCCESS(rv);
- if (state == OVER) {
- break;
- }
- ABTS_INT_EQUAL(tc, 1, (state == PONG));
- } while (state == PING);
+ ABTS_TRUE(tc, state == PONG || state == OVER);
} while (state != OVER);
rv = apr_thread_mutex_unlock(box->mutex);