Warren DeLano added the comment:

Patch attached.  Do note that this patch will break threading on Win95 
in order to achieve 64-bit compatibility.  Win98 and up should be 
fine -- however, that assertion has not yet been confirmed.

Added file: http://bugs.python.org/file8621/thread_nt_fix.patch

__________________________________
Tracker <[EMAIL PROTECTED]>
<http://bugs.python.org/issue1332>
__________________________________
*** thread_nt.h Fri Oct 26 21:03:09 2007
--- Python-2.5.1/Python/thread_nt.h     Fri Oct 26 21:03:34 2007
***************
*** 1,9 ****
--- 1,10 ----
  
  /* This code implemented by [EMAIL PROTECTED] */
  /* Fast NonRecursiveMutex support by Yakov Markovitch, [EMAIL PROTECTED] */
  /* Eliminated some memory leaks, [EMAIL PROTECTED] */
+ /* Nixed InterlockedCompareExchange emulation (x86_64:1, Win95:0), [EMAIL 
PROTECTED] */
  
  #include <windows.h>
  #include <limits.h>
  #ifdef HAVE_PROCESS_H
  #include <process.h>
***************
*** 13,88 ****
        LONG   owned ;
        DWORD  thread_id ;
        HANDLE hevent ;
  } NRMUTEX, *PNRMUTEX ;
  
- typedef PVOID WINAPI interlocked_cmp_xchg_t(PVOID *dest, PVOID exc, PVOID 
comperand) ;
- 
- /* Sorry mate, but we haven't got InterlockedCompareExchange in Win95! */
- static PVOID WINAPI
- interlocked_cmp_xchg(PVOID *dest, PVOID exc, PVOID comperand)
- {
-       static LONG spinlock = 0 ;
-       PVOID result ;
-       DWORD dwSleep = 0;
- 
-       /* Acqire spinlock (yielding control to other threads if cant aquire 
for the moment) */
-       while(InterlockedExchange(&spinlock, 1))
-       {
-               // Using Sleep(0) can cause a priority inversion.
-               // Sleep(0) only yields the processor if there's
-               // another thread of the same priority that's
-               // ready to run.  If a high-priority thread is
-               // trying to acquire the lock, which is held by
-               // a low-priority thread, then the low-priority
-               // thread may never get scheduled and hence never
-               // free the lock.  NT attempts to avoid priority
-               // inversions by temporarily boosting the priority
-               // of low-priority runnable threads, but the problem
-               // can still occur if there's a medium-priority
-               // thread that's always runnable.  If Sleep(1) is used,
-               // then the thread unconditionally yields the CPU.  We
-               // only do this for the second and subsequent even
-               // iterations, since a millisecond is a long time to wait
-               // if the thread can be scheduled in again sooner
-               // (~100,000 instructions).
-               // Avoid priority inversion: 0, 1, 0, 1,...
-               Sleep(dwSleep);
-               dwSleep = !dwSleep;
-       }
-       result = *dest ;
-       if (result == comperand)
-               *dest = exc ;
-       /* Release spinlock */
-       spinlock = 0 ;
-       return result ;
- } ;
- 
- static interlocked_cmp_xchg_t *ixchg;
- 
  BOOL
  InitializeNonRecursiveMutex(PNRMUTEX mutex)
  {
-       if (!ixchg)
-       {
-               /* Sorely, Win95 has no InterlockedCompareExchange API (Win98 
has), so we have to use emulation */
-               HANDLE kernel = GetModuleHandle("kernel32.dll") ;
-               if (!kernel || (ixchg = (interlocked_cmp_xchg_t 
*)GetProcAddress(kernel, "InterlockedCompareExchange")) == NULL)
-                       ixchg = interlocked_cmp_xchg ;
-       }
- 
        mutex->owned = -1 ;  /* No threads have entered NonRecursiveMutex */
        mutex->thread_id = 0 ;
        mutex->hevent = CreateEvent(NULL, FALSE, FALSE, NULL) ;
        return mutex->hevent != NULL ;  /* TRUE if the mutex is created */
  }
  
- #ifdef InterlockedCompareExchange
- #undef InterlockedCompareExchange
- #endif
- #define InterlockedCompareExchange(dest,exchange,comperand) (ixchg((dest), 
(exchange), (comperand)))
- 
  VOID
  DeleteNonRecursiveMutex(PNRMUTEX mutex)
  {
        /* No in-use check */
        CloseHandle(mutex->hevent) ;
--- 14,32 ----
***************
*** 96,106 ****
        DWORD ret ;
  
        /* InterlockedIncrement(&mutex->owned) == 0 means that no thread 
currently owns the mutex */
        if (!wait)
        {
!               if (InterlockedCompareExchange((PVOID *)&mutex->owned, 
(PVOID)0, (PVOID)-1) != (PVOID)-1)
                        return WAIT_TIMEOUT ;
                ret = WAIT_OBJECT_0 ;
        }
        else
                ret = InterlockedIncrement(&mutex->owned) ?
--- 40,50 ----
        DWORD ret ;
  
        /* InterlockedIncrement(&mutex->owned) == 0 means that no thread 
currently owns the mutex */
        if (!wait)
        {
!               if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1)
                        return WAIT_TIMEOUT ;
                ret = WAIT_OBJECT_0 ;
        }
        else
                ret = InterlockedIncrement(&mutex->owned) ?
_______________________________________________
Python-bugs-list mailing list 
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to