summaryrefslogtreecommitdiff
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1992-08-04 12:41:02 +0000
committerGuido van Rossum <guido@python.org>1992-08-04 12:41:02 +0000
commit1984f1e1c6306d4e8073c28d2395638f80ea509b (patch)
tree4366039e7665e689aef04549c3e3d73f99bdab32 /Python/ceval.c
parent4fbf798f866b10ee50cc91a394d19c0d4b2f79ab (diff)
downloadcpython-git-1984f1e1c6306d4e8073c28d2395638f80ea509b.tar.gz
* 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
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c96
1 files changed, 93 insertions, 3 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 0b2f924a84..32c52c7352 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -84,6 +84,79 @@ static object *build_class PROTO((object *, object *));
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 @@ eval_code(co, globals, locals, arg)
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();