* Makefile adapted to changes below.
* split pythonmain.c in two: most stuff goes to pythonrun.c, in the library.
* new optional built-in threadmodule.c, build upon Sjoerd's thread.{c,h}.
* new module from Sjoerd: mmmodule.c (dynamically loaded).
* new module from Sjoerd: sv (svgen.py, svmodule.c.proto).
* new files thread.{c,h} (from Sjoerd).
* new xxmodule.c (example only).
* myselect.h: bzero -> memset
* select.c: bzero -> memset; removed global variable
diff --git a/Python/ceval.c b/Python/ceval.c
index 0b2f924..32c52c7 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -84,6 +84,79 @@
 static frameobject *current_frame;
 
 
+/* Interface for threads.
+
+   A module that plans to do a blocking system call (or something else
+   that lasts a long time and doesn't touch Python data) can allow other
+   threads to run as follows:
+
+	void *x;
+
+	...preparations here...
+	x = save_thread();
+	...blocking system call here...
+	restore_thread(x);
+	...interpretr result here...
+
+   For convenience, that the value of 'errno' is restored across the
+   the call to restore_thread().
+
+   The function init_save_thread() should be called only from
+   initthread() in "threadmodule.c".
+
+   Note that not yet all candidates have been converted to use this
+   mechanism!
+*/
+
+#ifdef USE_THREAD
+#include <errno.h>
+#include "thread.h"
+static type_lock interpreter_lock;
+
+void
+init_save_thread()
+{
+#ifdef USE_THREAD
+	if (interpreter_lock)
+		fatal("2nd call to init_save_thread");
+	interpreter_lock = allocate_lock();
+	acquire_lock(interpreter_lock, 1);
+#endif
+}
+#endif
+
+void *
+save_thread()
+{
+#ifdef USE_THREAD
+	if (interpreter_lock) {
+		void *res;
+		res = (void *)current_frame;
+		current_frame = NULL;
+		release_lock(interpreter_lock);
+		return res;
+	}
+	else
+		return NULL;
+#endif
+}
+
+void
+restore_thread(x)
+	void *x;
+{
+#ifdef USE_THREAD
+	if (interpreter_lock) {
+		int err;
+		err = errno;
+		acquire_lock(interpreter_lock, 1);
+		errno = err;
+		current_frame = (frameobject *)x;
+	}
+#endif
+}
+
+
 /* Status code for main loop (reason for stack unwind) */
 
 enum why_code {
@@ -210,17 +283,34 @@
 	for (;;) {
 		static int ticker;
 		
-		/* Do periodic things */
+		/* Do periodic things.
+		   Doing this every time through the loop would add
+		   too much overhead (a function call per instruction).
+		   So we do it only every tenth instruction. */
 		
 		if (--ticker < 0) {
-			ticker = 100;
+			ticker = 10;
 			if (intrcheck()) {
 				err_set(KeyboardInterrupt);
 				why = WHY_EXCEPTION;
 				goto on_error;
 			}
+
+#ifdef USE_THREAD
+			if (interpreter_lock) {
+				/* Give another thread a chance */
+
+				current_frame = NULL;
+				release_lock(interpreter_lock);
+
+				/* Other threads may run now */
+
+				acquire_lock(interpreter_lock, 1);
+				current_frame = f;
+			}
+#endif
 		}
-		
+
 		/* Extract opcode and argument */
 		
 		opcode = NEXTOP();