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