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