[Python-checkins] r75693 - in sandbox/trunk/newgil: Include/ceval.h Lib/test/test_sys.py Python/ceval_gil.h Python/sysmodule.c

antoine.pitrou python-checkins at python.org
Sun Oct 25 19:12:23 CET 2009


Author: antoine.pitrou
Date: Sun Oct 25 19:12:23 2009
New Revision: 75693

Log:
Add a sys.setswitchinterval()/getswitchinterval() to set the desired 
interval between thread switches (in seconds).



Modified:
   sandbox/trunk/newgil/Include/ceval.h
   sandbox/trunk/newgil/Lib/test/test_sys.py
   sandbox/trunk/newgil/Python/ceval_gil.h
   sandbox/trunk/newgil/Python/sysmodule.c

Modified: sandbox/trunk/newgil/Include/ceval.h
==============================================================================
--- sandbox/trunk/newgil/Include/ceval.h	(original)
+++ sandbox/trunk/newgil/Include/ceval.h	Sun Oct 25 19:12:23 2009
@@ -171,6 +171,9 @@
 PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate);
 PyAPI_FUNC(void) PyEval_ReInitThreads(void);
 
+PyAPI_FUNC(void) _PyEval_SetSwitchInterval(double seconds);
+PyAPI_FUNC(double) _PyEval_GetSwitchInterval(void);
+
 #define Py_BEGIN_ALLOW_THREADS { \
 			PyThreadState *_save; \
 			_save = PyEval_SaveThread();

Modified: sandbox/trunk/newgil/Lib/test/test_sys.py
==============================================================================
--- sandbox/trunk/newgil/Lib/test/test_sys.py	(original)
+++ sandbox/trunk/newgil/Lib/test/test_sys.py	Sun Oct 25 19:12:23 2009
@@ -148,6 +148,21 @@
             sys.setcheckinterval(n)
             self.assertEquals(sys.getcheckinterval(), n)
 
+    def test_switchinterval(self):
+        self.assertRaises(TypeError, sys.setswitchinterval)
+        self.assertRaises(TypeError, sys.setswitchinterval, "a")
+        self.assertRaises(ValueError, sys.setswitchinterval, -1.0)
+        self.assertRaises(ValueError, sys.setswitchinterval, 0.0)
+        orig = sys.getswitchinterval()
+        # sanity check
+        self.assertTrue(orig < 0.5, orig)
+        try:
+            for n in 0.00001, 0.05, 3.0, orig:
+                sys.setswitchinterval(n)
+                self.assertAlmostEquals(sys.getswitchinterval(), n)
+        finally:
+            sys.setswitchinterval(orig)
+
     def test_recursionlimit(self):
         self.assertRaises(TypeError, sys.getrecursionlimit, 42)
         oldlimit = sys.getrecursionlimit()

Modified: sandbox/trunk/newgil/Python/ceval_gil.h
==============================================================================
--- sandbox/trunk/newgil/Python/ceval_gil.h	(original)
+++ sandbox/trunk/newgil/Python/ceval_gil.h	Sun Oct 25 19:12:23 2009
@@ -8,10 +8,12 @@
 
 /* First some general settings */
 
-/* milliseconds */
-#define INTERVAL 5
+/* milliseconds (the public API uses seconds, though) */
+#define DEFAULT_INTERVAL 5
+static double gil_interval = DEFAULT_INTERVAL;
+#define INTERVAL (gil_interval >= 1.0 ? gil_interval : 1.0)
 
-/* Enable if you want to force the switching of threads at least every INTERVAL */
+/* Enable if you want to force the switching of threads at least every `gil_interval` */
 #undef FORCE_SWITCHING
 #define FORCE_SWITCHING
 
@@ -39,7 +41,7 @@
 
 #define ADD_MILLISECONDS(tv, interval) \
 do { \
-    tv.tv_usec += interval * 1000; \
+    tv.tv_usec += (long) interval * 1000; \
     tv.tv_sec += tv.tv_usec / 1000000; \
     tv.tv_usec %= 1000000; \
 } while (0)
@@ -80,7 +82,7 @@
         struct timeval deadline; \
         \
         GETTIMEOFDAY(&deadline); \
-        ADD_MILLISECONDS(deadline, INTERVAL); \
+        ADD_MILLISECONDS(deadline, milliseconds); \
         ts.tv_sec = deadline.tv_sec; \
         ts.tv_nsec = deadline.tv_usec * 1000; \
         \
@@ -356,3 +358,15 @@
 {
     _take_gil(tstate, 1);
 }
+
+void _PyEval_SetSwitchInterval(double seconds)
+{
+    if (seconds <= 0)
+        Py_FatalError("switch interval must be strictly positive");
+    gil_interval = seconds * 1000.0;
+}
+
+double _PyEval_GetSwitchInterval()
+{
+    return gil_interval / 1000.0;
+}

Modified: sandbox/trunk/newgil/Python/sysmodule.c
==============================================================================
--- sandbox/trunk/newgil/Python/sysmodule.c	(original)
+++ sandbox/trunk/newgil/Python/sysmodule.c	Sun Oct 25 19:12:23 2009
@@ -441,9 +441,6 @@
 	return temp;
 }
 
-/* TODO: deprecate */
-static int _check_interval = 100;
-
 PyDoc_STRVAR(getprofile_doc,
 "getprofile()\n\
 \n\
@@ -451,6 +448,9 @@
 See the profiler chapter in the library manual."
 );
 
+/* TODO: deprecate */
+static int _check_interval = 100;
+
 static PyObject *
 sys_setcheckinterval(PyObject *self, PyObject *args)
 {
@@ -477,6 +477,47 @@
 "getcheckinterval() -> current check interval; see setcheckinterval()."
 );
 
+#ifdef WITH_THREAD
+static PyObject *
+sys_setswitchinterval(PyObject *self, PyObject *args)
+{
+	double d;
+	if (!PyArg_ParseTuple(args, "d:setswitchinterval", &d))
+		return NULL;
+	if (d <= 0.0) {
+		PyErr_SetString(PyExc_ValueError,
+				"switch interval must be strictly positive");
+		return NULL;
+	}
+	_PyEval_SetSwitchInterval(d);
+	Py_INCREF(Py_None);
+	return Py_None;
+}
+
+PyDoc_STRVAR(setswitchinterval_doc,
+"setswitchinterval(n)\n\
+\n\
+Set the ideal thread switching delay inside the Python interpreter\n\
+The actual frequency of switching threads can be lower if the\n\
+interpreter executes long sequences of uninterruptible code\n\
+(this is implementation-specific and workload-dependent).\n\
+\n\
+The parameter must represent the desired switching delay in seconds\n\
+A typical value is 0.005 (5 milliseconds)."
+);
+
+static PyObject *
+sys_getswitchinterval(PyObject *self, PyObject *args)
+{
+	return PyFloat_FromDouble(_PyEval_GetSwitchInterval());
+}
+
+PyDoc_STRVAR(getswitchinterval_doc,
+"getswitchinterval() -> current thread switch interval; see setswitchinterval()."
+);
+
+#endif /* WITH_THREAD */
+
 #ifdef WITH_TSC
 static PyObject *
 sys_settscdump(PyObject *self, PyObject *args)
@@ -898,6 +939,12 @@
 	 setcheckinterval_doc},
 	{"getcheckinterval",	sys_getcheckinterval, METH_NOARGS,
 	 getcheckinterval_doc},
+#ifdef WITH_THREAD
+	{"setswitchinterval",	sys_setswitchinterval, METH_VARARGS,
+	 setswitchinterval_doc},
+	{"getswitchinterval",	sys_getswitchinterval, METH_NOARGS,
+	 getswitchinterval_doc},
+#endif
 #ifdef HAVE_DLOPEN
 	{"setdlopenflags", sys_setdlopenflags, METH_VARARGS,
 	 setdlopenflags_doc},


More information about the Python-checkins mailing list