]> granicus.if.org Git - python/commitdiff
Fix problems in x64 build that were discovered by the testsuite:
authorKristján Valur Jónsson <kristjan@ccpgames.com>
Thu, 3 May 2007 20:27:03 +0000 (20:27 +0000)
committerKristján Valur Jónsson <kristjan@ccpgames.com>
Thu, 3 May 2007 20:27:03 +0000 (20:27 +0000)
- 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.

Modules/itertoolsmodule.c
Modules/posixmodule.c
Objects/intobject.c
Objects/longobject.c
PC/config.c
PC/pyconfig.h
Python/thread_nt.h

index 8fe484a770a09fb38f2265e6777e19170991bf2f..33172b6775f5b69cc781f243753f63182216a3e0 100644 (file)
@@ -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++);
index a63a77a3d5a81186b0e108ef047724414458024a..2b62983bd22ecd4a60a7dd5b2bc5e15f32bdba4d 100644 (file)
@@ -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
index 9ffc2950f2e00a60dbaa376aa8d79af527ccd0c8..a82b3c889e53c1466cbeb0f693606f6592bf202e 100644 (file)
@@ -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);
        }
index 6d55354bf6b8a41fc61c5d48fe85af9cdaff8196..a8663bc9063e8051513c3d41da7c375429464c5c 100644 (file)
@@ -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. */
index e1b52a4f232b63b5c8751309ad0be624af7c7761..6860211eb64ad85ecc4b8563ee67893252b6e6fe 100644 (file)
@@ -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},
index f2ef7f95b8ae85a793f848a030edbe49f3f24c79..10d929a79a16f10f88fb059ce0f2ab71ce0030b9 100644 (file)
@@ -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
index 27fca72cd88c7d0381cee76bb4dfd69f51a26898..944552992f4f442d8d445a5f953b9bb96ff3b6c9 100644 (file)
@@ -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".