dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/engine lib_thread.c,1.17,1.18


From: Thong Nguyen <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/engine lib_thread.c,1.17,1.18
Date: Mon, 07 Jul 2003 12:01:01 -0400

Update of /cvsroot/dotgnu-pnet/pnet/engine
In directory subversions:/tmp/cvs-serv26303/engine

Modified Files:
        lib_thread.c 
Log Message:
Monitor speed improvements.  Fix monitor free list race condition


Index: lib_thread.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/lib_thread.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -r1.17 -r1.18
*** lib_thread.c        6 Jul 2003 09:19:36 -0000       1.17
--- lib_thread.c        7 Jul 2003 16:00:59 -0000       1.18
***************
*** 1,2 ****
--- 1,3 ----
+ 
  /*
   * lib_thread.c - Internalcall methods for "System.Threading.*".
***************
*** 29,33 ****
  
  /*
!  *    Comments on terminology:
   *
   * Support Thread:    Refers to an ILThread instance.
--- 30,34 ----
  
  /*
!  * Comments on terminology:
   *
   * Support Thread:    Refers to an ILThread instance.
***************
*** 37,41 ****
  
  /*
!  *    Timeout value the managed WaitHandle uses.
   */
  #define WIN32_WAIT_TIMEOUT (258L)
--- 38,42 ----
  
  /*
!  * Timeout value the managed WaitHandle uses.
   */
  #define WIN32_WAIT_TIMEOUT (258L)
***************
*** 65,69 ****
  
  /*
!  *    Spins until the object is unmarked and the current thread can mark it.
   */
  static void _IL_ObjectLockword_WaitAndMark(ILExecThread *thread, volatile 
ILObject *obj)
--- 66,70 ----
  
  /*
!  * Spins until the object is unmarked and the current thread can mark it.
   */
  static void _IL_ObjectLockword_WaitAndMark(ILExecThread *thread, volatile 
ILObject *obj)
***************
*** 84,88 ****
  
  /*
!  *    Unmarks an object's lockword.
   */
  static void _IL_ObjectLockword_Unmark(ILExecThread *thread, volatile ILObject 
*obj)
--- 85,89 ----
  
  /*
!  * Unmarks an object's lockword.
   */
  static void _IL_ObjectLockword_Unmark(ILExecThread *thread, volatile ILObject 
*obj)
***************
*** 96,113 ****
  
  /*
!  *    Checks if the monitor is longer being used and returns it to the free 
list and
!  * zeros 
   */
  static int _IL_Monitor_CheckAndReturnMonitorToFreeList(ILExecThread *thread, 
ILExecMonitor *monitor, volatile ILObject *obj)
  {     
!       if (monitor->waiters == 0 && 
ILWaitMonitorCanClose(monitor->supportMonitor))
        {
                /* Remove the monitor from the object if the object hasn't been 
assigned
                      a new monitor */
!               CompareAndExchangeObjectLockWord(thread, obj, 0, 
IL_LW_MARK(monitor));
!               
!               /* Return the monitor to the free list */
!               monitor->next = thread->freeMonitor;
!               thread->freeMonitor = monitor;
  
                return 1;
--- 97,132 ----
  
  /*
!  * Checks if the monitor is longer being used and returns it to the free list 
and
!  * zeros the object's lockword.
!  *
!  * This method is only safe to call if you have exclusive acess to the 
object's
!  * lockword.
   */
  static int _IL_Monitor_CheckAndReturnMonitorToFreeList(ILExecThread *thread, 
ILExecMonitor *monitor, volatile ILObject *obj)
  {     
!       if(monitor->waiters == 0 && 
ILWaitMonitorCanClose(monitor->supportMonitor))
        {
+               ILLockWord current;
+ 
                /* Remove the monitor from the object if the object hasn't been 
assigned
                      a new monitor */
!               current = CompareAndExchangeObjectLockWord(thread, obj, 0, 
IL_LW_MARK(monitor));
! 
!               if(current == IL_LW_MARK(monitor))
!               {
!                       /* The object's monitor hasn't changed (or has changed 
and
!                          has become 'monitor' again) so no other thread claims
!                          this monitor as free */
! 
!                       /* Return the monitor to this thread's free list */
! 
!                       monitor->next = thread->freeMonitor;
!                       thread->freeMonitor = monitor;
!               }
!               else
!               {
!                       /* The object's monitor has changed which means 
'monitor'
!                          has already been claimed as as free by another 
thread */
!               }
  
                return 1;
***************
*** 178,202 ****
                                thread,
                                obj,
!                               monitor,
                                lockword
                        ) == lockword)
                {
                        /* Succesfully installed the new monitor */
                        
                        /* Remove the monitor from the free list */
  
                        thread->freeMonitor = next;
  
!                       /* Compete for the monitor */
  
!                       goto retry;
                }
                else
                {
!                       /* A thread managed to install a monitor first.
!                                       Add the monitor to the free list and 
retry. */
  
!                       monitor->next = thread->freeMonitor;
!                       thread->freeMonitor = monitor;
  
                        goto retry;
--- 197,250 ----
                                thread,
                                obj,
!                               IL_LW_MARK(monitor),
                                lockword
                        ) == lockword)
                {
                        /* Succesfully installed the new monitor */
+ 
+                       /* Let the support monitor know we've entered */
+                       result = ILWaitMonitorEnter(monitor->supportMonitor);
+ 
+                       if (result != 0)
+                       {
+                               /* Dissociate the monitor from the object */
+                               /* No need to do extensive checks (i.e. call
+                                  CheckAndReturnMonitorToFreeList) since it's
+                                  impossible for other threads to have managed
+                                  to call Enter on this monitor */
+ 
+                               SetObjectLockWord(thread, obj, 0);
                        
+                               /* If the monitor is new, add it to the free 
list */
+                               if (monitor != thread->freeMonitor)
+                               {
+                                       monitor->next = thread->freeMonitor;
+                                       thread->freeMonitor = monitor;
+                               }                               
+ 
+                               HandleWaitResult(thread, result);
+ 
+                               return 0;
+                       }
+ 
                        /* Remove the monitor from the free list */
  
                        thread->freeMonitor = next;
  
!                       /* Finally allow other threads to enter the monitor */
!                       _IL_ObjectLockword_Unmark(thread, obj);
  
!                       return 1;
                }
                else
                {
!                       /* Another thread managed to install a monitor first */
  
!                       /* If the monitor is new, add it to the free list */
!                       if (monitor != thread->freeMonitor)
!                       {
!                               monitor->next = thread->freeMonitor;
!                               thread->freeMonitor = monitor;
!                       }
  
                        goto retry;
***************
*** 209,212 ****
--- 257,261 ----
        {
                /* Spin */
+ 
                goto retry;
        }
***************
*** 218,222 ****
  
        /* Now double check and see if another thread is trying to exit
!              now that monitor->waiters has been incremented monitor */
        lockword = GetObjectLockWord(thread, obj);
        
--- 267,271 ----
  
        /* Now double check and see if another thread is trying to exit
!              now that monitor->waiters has been incremented */
        lockword = GetObjectLockWord(thread, obj);
        
***************
*** 260,267 ****
                /* Unmark the object's lockword */
                _IL_ObjectLockword_Unmark(thread, obj);
-       }
  
!       /* Handle ThreadAbort etc */    
!       HandleWaitResult(thread, result);
  
        return result == 0;
--- 309,316 ----
                /* Unmark the object's lockword */
                _IL_ObjectLockword_Unmark(thread, obj);
  
!               /* Handle ThreadAbort etc */    
!               HandleWaitResult(thread, result);
!       }
  
        return result == 0;
***************
*** 393,397 ****
  
        _IL_Interlocked_Increment_Ri(thread, (ILInt32 *)&monitor->waiters);
!       
        lockword = GetObjectLockWord(thread, obj);
  
--- 442,448 ----
  
        _IL_Interlocked_Increment_Ri(thread, (ILInt32 *)&monitor->waiters);
! 
!       /* Now double check and see if another thread is trying to exit
!              now that monitor->waiters has been incremented */        
        lockword = GetObjectLockWord(thread, obj);
  





reply via email to

[Prev in Thread] Current Thread [Next in Thread]