From f030394de333ed645e7f1139e2e42f43444efb73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Valur=20J=C3=B3nsson?= Date: Thu, 3 May 2007 20:27:03 +0000 Subject: =?UTF-8?q?Fix=20problems=20in=20x64=20build=20that=20were=20disco?= =?UTF-8?q?vered=20by=20the=20testsuite:=20-=20Reenable=20modules=20on=20x?= =?UTF-8?q?64=20that=20had=20been=20disabled=20aeons=20ago=20for=20Itanium?= =?UTF-8?q?.=20-=20Cleared=20up=20confusion=20about=20compilers=20for=2064?= =?UTF-8?q?=20bit=20windows.=20=20There=20is=20only=20Itanium=20and=20x64.?= =?UTF-8?q?=20=20Added=20macros=20MS=5FWINI64=20and=20MS=5FWINX64=20for=20?= =?UTF-8?q?those=20rare=20cases=20where=20it=20matters,=20such=20as=20the?= =?UTF-8?q?=20disabling=20of=20modules=20above.=20-=20Set=20target=20platf?= =?UTF-8?q?orm=20(=5FWIN32=5FWINNT=20and=20WINVER)=20to=200x0501=20(XP)=20?= =?UTF-8?q?for=20x64,=20and=200x0400=20(NT=204.0)=20otherwise,=20which=20a?= =?UTF-8?q?re=20the=20targeted=20minimum=20platforms.=20-=20Fixed=20thread?= =?UTF-8?q?=5Fnt.h.=20=20The=20emulated=20InterlockedCompareExchange=20fun?= =?UTF-8?q?ction=20didn=C2=B4t=20work=20on=20x64,=20probaby=20due=20to=20t?= =?UTF-8?q?he=20lack=20of=20a=20"volatile"=20specifier.=20=20Anyway,=20win?= =?UTF-8?q?95=20is=20no=20longer=20a=20target=20platform.=20-=20Itertools?= =?UTF-8?q?=20module=20used=20wrong=20constant=20to=20check=20for=20overfl?= =?UTF-8?q?ow=20in=20count()=20-=20PyInt=5FAsSsize=5Ft=20couldn't=20deal?= =?UTF-8?q?=20with=20attribute=20error=20when=20accessing=20the=20=5F=5Flo?= =?UTF-8?q?ng=5F=5F=20member.=20-=20PyLong=5FFromSsize=5Ft()=20incorrectly?= =?UTF-8?q?=20specified=20that=20the=20operand=20were=20unsigned.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With these changes, the x64 passes the testsuite, for those modules present. --- Modules/itertoolsmodule.c | 4 +-- Modules/posixmodule.c | 1 - Objects/intobject.c | 4 +++ Objects/longobject.c | 2 +- PC/config.c | 12 ++++----- PC/pyconfig.h | 23 +++++++++++++---- Python/thread_nt.h | 63 ++++------------------------------------------- 7 files changed, 36 insertions(+), 73 deletions(-) diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c index 8fe484a..33172b6 100644 --- a/Modules/itertoolsmodule.c +++ b/Modules/itertoolsmodule.c @@ -2073,9 +2073,9 @@ count_new(PyTypeObject *type, PyObject *args, PyObject *kwds) static PyObject * count_next(countobject *lz) { - if (lz->cnt == LONG_MAX) { + if (lz->cnt == PY_SSIZE_T_MAX) { PyErr_SetString(PyExc_OverflowError, - "cannot count beyond LONG_MAX"); + "cannot count beyond PY_SSIZE_T_MAX"); return NULL; } return PyInt_FromSsize_t(lz->cnt++); diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index a63a77a..2b62983 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -263,7 +263,6 @@ extern int lstat(const char *, struct stat *); #include #endif #include "osdefs.h" -#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */ #include #include /* for ShellExecute() */ #define popen _popen diff --git a/Objects/intobject.c b/Objects/intobject.c index 9ffc295..a82b3c8 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -215,6 +215,10 @@ PyInt_AsSsize_t(register PyObject *op) if (nb->nb_long != 0) { io = (PyIntObject*) (*nb->nb_long) (op); + if (io == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + io = (PyIntObject*) (*nb->nb_int) (op); + } } else { io = (PyIntObject*) (*nb->nb_int) (op); } diff --git a/Objects/longobject.c b/Objects/longobject.c index 6d55354..a8663bc 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -893,7 +893,7 @@ _PyLong_FromSsize_t(Py_ssize_t ival) int one = 1; return _PyLong_FromByteArray( (unsigned char *)&bytes, - SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0); + SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1); } /* Create a new long int object from a C size_t. */ diff --git a/PC/config.c b/PC/config.c index e1b52a4..6860211 100644 --- a/PC/config.c +++ b/PC/config.c @@ -6,21 +6,21 @@ #include "Python.h" extern void initarray(void); -#ifndef MS_WIN64 +#ifndef MS_WINI64 extern void initaudioop(void); #endif extern void initbinascii(void); extern void initcmath(void); extern void initerrno(void); extern void initgc(void); -#ifndef MS_WIN64 +#ifndef MS_WINI64 extern void initimageop(void); #endif extern void initmath(void); extern void init_md5(void); extern void initnt(void); extern void initoperator(void); -#ifndef MS_WIN64 +#ifndef MS_WINI64 extern void initrgbimg(void); #endif extern void initsignal(void); @@ -80,7 +80,7 @@ struct _inittab _PyImport_Inittab[] = { {"array", initarray}, {"_ast", init_ast}, #ifdef MS_WINDOWS -#ifndef MS_WIN64 +#ifndef MS_WINI64 {"audioop", initaudioop}, #endif #endif @@ -88,14 +88,14 @@ struct _inittab _PyImport_Inittab[] = { {"cmath", initcmath}, {"errno", initerrno}, {"gc", initgc}, -#ifndef MS_WIN64 +#ifndef MS_WINI64 {"imageop", initimageop}, #endif {"math", initmath}, {"_md5", init_md5}, {"nt", initnt}, /* Use the NT os functions, not posix */ {"operator", initoperator}, -#ifndef MS_WIN64 +#ifndef MS_WINI64 {"rgbimg", initrgbimg}, #endif {"signal", initsignal}, diff --git a/PC/pyconfig.h b/PC/pyconfig.h index f2ef7f95..10d929a 100644 --- a/PC/pyconfig.h +++ b/PC/pyconfig.h @@ -128,6 +128,8 @@ MS_CORE_DLL. defined on Win32 *and* Win64. Win32 only code must therefore be guarded as follows: #if defined(MS_WIN32) && !defined(MS_WIN64) + Some modules are disabled on Itanium processors, therefore we + have MS_WINI64 set for those targets, otherwise MS_WINX64 */ #ifdef _WIN64 #define MS_WIN64 @@ -135,17 +137,28 @@ MS_CORE_DLL. /* set the COMPILER */ #ifdef MS_WIN64 -#ifdef _M_IX86 -#define COMPILER _Py_PASTE_VERSION("64 bit (Intel)") -#elif defined(_M_IA64) +#if defined(_M_IA64) #define COMPILER _Py_PASTE_VERSION("64 bit (Itanium)") -#elif defined(_M_AMD64) -#define COMPILER _Py_PASTE_VERSION("64 bit (AMD64)") +#define MS_WINI64 +#elif defined(_M_X64) +#define COMPILER _Py_PASTE_VERSION("64 bit (x64)") +#define MS_WINX64 #else #define COMPILER _Py_PASTE_VERSION("64 bit (Unknown)") #endif #endif /* MS_WIN64 */ +/* set the version macros for the windows headers */ +#ifdef MS_WINX64 +/* 64 bit only runs on XP or greater */ +#define _WIN32_WINNT 0x0501 +#define WINVER 0x0501 +#else +/* NT 4.0 or greater required otherwise */ +#define _WIN32_WINNT 0x0400 +#define WINVER 0x0400 +#endif + /* _W64 is not defined for VC6 or eVC4 */ #ifndef _W64 #define _W64 diff --git a/Python/thread_nt.h b/Python/thread_nt.h index 27fca72..9445529 100644 --- a/Python/thread_nt.h +++ b/Python/thread_nt.h @@ -15,72 +15,16 @@ typedef struct NRMUTEX { 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) { @@ -98,7 +42,7 @@ EnterNonRecursiveMutex(PNRMUTEX mutex, BOOL wait) /* 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) + if (InterlockedCompareExchange(&mutex->owned, 0, -1) != -1) return WAIT_TIMEOUT ; ret = WAIT_OBJECT_0 ; } @@ -196,7 +140,10 @@ PyThread_start_new_thread(void (*func)(void *), void *arg) if (obj.done == NULL) return -1; - rv = _beginthread(bootstrap, _pythread_stacksize, &obj); + rv = _beginthread(bootstrap, + Py_SAFE_DOWNCAST(_pythread_stacksize, + Py_ssize_t, int), + &obj); if (rv == (Py_uintptr_t)-1) { /* I've seen errno == EAGAIN here, which means "there are * too many threads". -- cgit v0.12