diff options
author | Guido van Rossum <guido@python.org> | 1992-08-04 12:41:02 +0000 |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-08-04 12:41:02 +0000 |
commit | 1984f1e1c6306d4e8073c28d2395638f80ea509b (patch) | |
tree | 4366039e7665e689aef04549c3e3d73f99bdab32 /Python/ceval.c | |
parent | 4fbf798f866b10ee50cc91a394d19c0d4b2f79ab (diff) | |
download | cpython-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.c | 96 |
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(); |