summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKristján Valur Jónsson <kristjan@ccpgames.com>2007-05-03 20:27:03 (GMT)
committerKristján Valur Jónsson <kristjan@ccpgames.com>2007-05-03 20:27:03 (GMT)
commitf030394de333ed645e7f1139e2e42f43444efb73 (patch)
tree3c9a6131bcfa6edeb265c63f2a531adc00d05214
parent170eee9d6ae4ad4270cfd164c046c2381d746191 (diff)
downloadcpython-f030394de333ed645e7f1139e2e42f43444efb73.zip
cpython-f030394de333ed645e7f1139e2e42f43444efb73.tar.gz
cpython-f030394de333ed645e7f1139e2e42f43444efb73.tar.bz2
Fix problems in x64 build that were discovered by the testsuite:
- Reenable modules on x64 that had been disabled aeons ago for Itanium. - Cleared up confusion about compilers for 64 bit windows. There is only Itanium and x64. Added macros MS_WINI64 and MS_WINX64 for those rare cases where it matters, such as the disabling of modules above. - Set target platform (_WIN32_WINNT and WINVER) to 0x0501 (XP) for x64, and 0x0400 (NT 4.0) otherwise, which are the targeted minimum platforms. - Fixed thread_nt.h. The emulated InterlockedCompareExchange function didn´t work on x64, probaby due to the lack of a "volatile" specifier. Anyway, win95 is no longer a target platform. - Itertools module used wrong constant to check for overflow in count() - PyInt_AsSsize_t couldn't deal with attribute error when accessing the __long__ member. - PyLong_FromSsize_t() incorrectly specified that the operand were unsigned. With these changes, the x64 passes the testsuite, for those modules present.
-rw-r--r--Modules/itertoolsmodule.c4
-rw-r--r--Modules/posixmodule.c1
-rw-r--r--Objects/intobject.c4
-rw-r--r--Objects/longobject.c2
-rw-r--r--PC/config.c12
-rw-r--r--PC/pyconfig.h23
-rw-r--r--Python/thread_nt.h63
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 <process.h>
#endif
#include "osdefs.h"
-#define _WIN32_WINNT 0x0400 /* Needed for CryptoAPI on some systems */
#include <windows.h>
#include <shellapi.h> /* 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".