[Python-checkins] r55103 - in python/trunk: Modules/itertoolsmodule.c Modules/posixmodule.c Objects/intobject.c Objects/longobject.c PC/config.c PC/pyconfig.h Python/thread_nt.h

kristjan.jonsson python-checkins at python.org
Thu May 3 22:27:12 CEST 2007


Author: kristjan.jonsson
Date: Thu May  3 22:27:03 2007
New Revision: 55103

Modified:
   python/trunk/Modules/itertoolsmodule.c
   python/trunk/Modules/posixmodule.c
   python/trunk/Objects/intobject.c
   python/trunk/Objects/longobject.c
   python/trunk/PC/config.c
   python/trunk/PC/pyconfig.h
   python/trunk/Python/thread_nt.h
Log:
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.


Modified: python/trunk/Modules/itertoolsmodule.c
==============================================================================
--- python/trunk/Modules/itertoolsmodule.c	(original)
+++ python/trunk/Modules/itertoolsmodule.c	Thu May  3 22:27:03 2007
@@ -2073,9 +2073,9 @@
 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++);

Modified: python/trunk/Modules/posixmodule.c
==============================================================================
--- python/trunk/Modules/posixmodule.c	(original)
+++ python/trunk/Modules/posixmodule.c	Thu May  3 22:27:03 2007
@@ -263,7 +263,6 @@
 #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

Modified: python/trunk/Objects/intobject.c
==============================================================================
--- python/trunk/Objects/intobject.c	(original)
+++ python/trunk/Objects/intobject.c	Thu May  3 22:27:03 2007
@@ -215,6 +215,10 @@
 
 	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);
 	}

Modified: python/trunk/Objects/longobject.c
==============================================================================
--- python/trunk/Objects/longobject.c	(original)
+++ python/trunk/Objects/longobject.c	Thu May  3 22:27:03 2007
@@ -893,7 +893,7 @@
 	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. */

Modified: python/trunk/PC/config.c
==============================================================================
--- python/trunk/PC/config.c	(original)
+++ python/trunk/PC/config.c	Thu May  3 22:27:03 2007
@@ -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 @@
         {"array", initarray},
 	{"_ast", init_ast},
 #ifdef MS_WINDOWS
-#ifndef MS_WIN64
+#ifndef MS_WINI64
         {"audioop", initaudioop},
 #endif
 #endif
@@ -88,14 +88,14 @@
         {"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},

Modified: python/trunk/PC/pyconfig.h
==============================================================================
--- python/trunk/PC/pyconfig.h	(original)
+++ python/trunk/PC/pyconfig.h	Thu May  3 22:27:03 2007
@@ -128,6 +128,8 @@
    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 @@
 
 /* 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

Modified: python/trunk/Python/thread_nt.h
==============================================================================
--- python/trunk/Python/thread_nt.h	(original)
+++ python/trunk/Python/thread_nt.h	Thu May  3 22:27:03 2007
@@ -15,72 +15,16 @@
 	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 @@
 	/* 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 @@
 	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".


More information about the Python-checkins mailing list