WIN-06.1: win32-threads.cc
Adam Megacz
patches@lists.megacz.com
Thu Jan 31 17:14:00 GMT 2002
2002-01-31 Adam Megacz
* win32-threads.cc:
- (_Jv_CondWait, _Jv_CondNotify, _Jv_CondNotifyAll) Corrected
wait() algorithm to make it safe.
- (ensure_condvar_initialized, _Jv_CondInit, _Jv_CondDestroy)
Added lazy creation of Win32 Events for better performance
- (really_start) This now uses GC_CreateThread so boehm-gc
knows about new threads even when statically linked.
Index: win32-threads.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/win32-threads.cc,v
retrieving revision 1.4
diff -c -3 -p -r1.4 win32-threads.cc
*** win32-threads.cc 2001/05/22 06:47:48 1.4
--- win32-threads.cc 2002/02/01 01:04:53
*************** details. */
*** 15,21 ****
#ifdef HAVE_BOEHM_GC
extern "C"
{
- #include <boehm-config.h>
#include <gc.h>
};
#endif /* HAVE_BOEHM_GC */
--- 15,20 ----
*************** DWORD _Jv_ThreadDataKey;
*** 62,111 ****
// Condition variables.
//
! int
! _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos)
! {
! DWORD time;
! DWORD rval;
! // FIXME: check for mutex ownership?
_Jv_MutexUnlock (mu);
! if((millis == 0) && (nanos > 0))
! time = 1;
! else if(millis == 0)
! time = INFINITE;
! else
! time = millis;
! rval = WaitForSingleObject (*cv, time);
_Jv_MutexLock (mu);
! if (rval == WAIT_FAILED)
! return _JV_NOT_OWNER; // FIXME?
! else
! return 0;
}
! //
! // Mutexes.
! //
! int
! _Jv_MutexLock (_Jv_Mutex_t *mu)
! {
! DWORD rval;
! // FIXME: Are Win32 mutexs recursive? Should we use critical section objects
! rval = WaitForSingleObject (*mu, INFINITE);
! if (rval == WAIT_FAILED)
! return GetLastError (); // FIXME: Map to errno?
! else if (rval == WAIT_TIMEOUT)
! return ETIMEDOUT;
! else
! return 0;
}
//
--- 61,144 ----
// Condition variables.
//
! // we do lazy creation of Events since CreateEvent() is insanely
! // expensive, and because the rest of libgcj will call _Jv_CondInit
! // when only a mutex is needed.
!
! inline void ensure_condvar_initialized(_Jv_ConditionVariable_t *cv) {
! if (cv->ev[0] == 0) {
! cv->ev[0] = CreateEvent (NULL, 0, 0, NULL);
! if (cv->ev[0] == 0) JvFail("CreateEvent() failed");
! cv->ev[1] = CreateEvent (NULL, 1, 0, NULL);
! if (cv->ev[1] == 0) JvFail("CreateEvent() failed");
! }
! }
! // Reimplementation of the general algorithm described at
! // http://www.cs.wustl.edu/~schmidt/win32-cv-1.html (isomorphic to
! // 3.2, not a cut-and-paste).
!
! int _Jv_CondWait(_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu, jlong millis, jint nanos) {
!
! EnterCriticalSection(&cv->count_mutex);
! ensure_condvar_initialized(cv);
! cv->blocked_count++;
! LeaveCriticalSection(&cv->count_mutex);
!
! DWORD time;
! if ((millis == 0) && (nanos > 0)) time = 1;
! else if (millis == 0) time = INFINITE;
! else time = millis;
_Jv_MutexUnlock (mu);
! DWORD rval = WaitForMultipleObjects (2, &(cv->ev[0]), 0, time);
!
! EnterCriticalSection(&cv->count_mutex);
! cv->blocked_count--;
! // if we were unblocked by the second event (the broadcast one) and nobody is left, reset the signal
! int last_waiter = rval == WAIT_OBJECT_0 + 1 && cv->blocked_count == 0;
! LeaveCriticalSection(&cv->count_mutex);
! if (last_waiter) ResetEvent(&cv->ev[1]);
!
_Jv_MutexLock (mu);
! if (rval == WAIT_FAILED) return GetLastError();
! else if (rval == WAIT_TIMEOUT) return ETIMEDOUT;
! else return 0;
}
! void _Jv_CondInit (_Jv_ConditionVariable_t *cv) {
! // we do lazy creation of Events since CreateEvent() is insanely expensive
! cv->ev[0] = 0;
! InitializeCriticalSection(&cv->count_mutex);
! cv->blocked_count = 0;
! }
! void _Jv_CondDestroy (_Jv_ConditionVariable_t *cv) {
! if (cv->ev[0] != 0) CloseHandle(cv->ev[0]);
! cv = NULL;
! }
! int _Jv_CondNotify (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *) {
! EnterCriticalSection(&cv->count_mutex);
! ensure_condvar_initialized(cv);
! int somebody_is_blocked = cv->blocked_count > 0;
! LeaveCriticalSection(&cv->count_mutex);
! if (somebody_is_blocked) return SetEvent (cv->ev[0]) ? 0 : GetLastError();
! else return 0;
! }
!
! int _Jv_CondNotifyAll (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *) {
! EnterCriticalSection(&cv->count_mutex);
! ensure_condvar_initialized(cv);
! int somebody_is_blocked = cv->blocked_count > 0;
! LeaveCriticalSection(&cv->count_mutex);
!
! if (somebody_is_blocked) return SetEvent (cv->ev[1]) ? 0 : GetLastError();
! else return 0;
}
//
*************** _Jv_ThreadUnRegister ()
*** 193,199 ****
// This function is called when a thread is started. We don't arrange
// to call the `run' method directly, because this function must
// return a value.
! static DWORD __stdcall
really_start (void* x)
{
struct starter *info = (struct starter *) x;
--- 226,232 ----
// This function is called when a thread is started. We don't arrange
// to call the `run' method directly, because this function must
// return a value.
! static DWORD WINAPI
really_start (void* x)
{
struct starter *info = (struct starter *) x;
*************** _Jv_ThreadStart (java::lang::Thread *thr
*** 239,245 ****
else
data->flags |= FLAG_DAEMON;
! HANDLE h = CreateThread(NULL, 0, really_start, info, 0, &id);
_Jv_ThreadSetPriority(data, thread->getPriority());
//if (!h)
--- 272,278 ----
else
data->flags |= FLAG_DAEMON;
! HANDLE h = GC_CreateThread(NULL, 0, really_start, info, 0, &id);
_Jv_ThreadSetPriority(data, thread->getPriority());
//if (!h)
More information about the Java-patches
mailing list