diff options
author | Guido van Rossum <guido@python.org> | 1992-08-04 12:41:02 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-08-04 12:41:02 (GMT) |
commit | 1984f1e1c6306d4e8073c28d2395638f80ea509b (patch) | |
tree | 4366039e7665e689aef04549c3e3d73f99bdab32 /Python | |
parent | 4fbf798f866b10ee50cc91a394d19c0d4b2f79ab (diff) | |
download | cpython-1984f1e1c6306d4e8073c28d2395638f80ea509b.zip cpython-1984f1e1c6306d4e8073c28d2395638f80ea509b.tar.gz cpython-1984f1e1c6306d4e8073c28d2395638f80ea509b.tar.bz2 |
* 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')
-rw-r--r-- | Python/ceval.c | 96 | ||||
-rw-r--r-- | Python/pythonmain.c | 384 | ||||
-rw-r--r-- | Python/pythonrun.c | 424 | ||||
-rw-r--r-- | Python/thread.c | 263 |
4 files changed, 783 insertions, 384 deletions
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 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(); diff --git a/Python/pythonmain.c b/Python/pythonmain.c index a141168..0f76bfd 100644 --- a/Python/pythonmain.c +++ b/Python/pythonmain.c @@ -26,23 +26,10 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "allobjects.h" -#include "grammar.h" -#include "node.h" -#include "parsetok.h" -#include "graminit.h" -#include "errcode.h" -#include "sysmodule.h" -#include "compile.h" -#include "ceval.h" -#include "pythonrun.h" -#include "import.h" - extern char *getpythonpath(); -extern grammar gram; /* From graminit.c */ - -int debugging; /* Needed by parser.c */ -int verbose; /* Needed by import.c */ +extern int debugging; /* Needed by parser.c */ +extern int verbose; /* Needed by import.c */ /* Interface to getopt(): */ extern int optind; @@ -108,12 +95,12 @@ main(argc, argv) initall(); - setpythonpath(getpythonpath()); if (command != NULL) { /* Backup optind and force sys.argv[0] = '-c' */ optind--; argv[optind] = "-c"; } + setpythonargv(argc-optind, argv+optind); if (command) { @@ -126,368 +113,3 @@ main(argc, argv) goaway(sts); /*NOTREACHED*/ } - -/* Initialize all */ - -void -initall() -{ - static int inited; - - if (inited) - return; - inited = 1; - - initimport(); - - /* Modules 'builtin' and 'sys' are initialized here, - they are needed by random bits of the interpreter. - All other modules are optional and should be initialized - by the initcalls() of a specific configuration. */ - - initbuiltin(); /* Also initializes builtin exceptions */ - initsys(); - - initcalls(); /* Configuration-dependent initializations */ - - initintr(); /* For intrcheck() */ -} - -/* Parse input from a file and execute it */ - -int -run(fp, filename) - FILE *fp; - char *filename; -{ - if (filename == NULL) - filename = "???"; - if (isatty((int)fileno(fp))) - return run_tty_loop(fp, filename); - else - return run_script(fp, filename); -} - -int -run_tty_loop(fp, filename) - FILE *fp; - char *filename; -{ - object *v; - int ret; - v = sysget("ps1"); - if (v == NULL) { - sysset("ps1", v = newstringobject(">>> ")); - XDECREF(v); - } - v = sysget("ps2"); - if (v == NULL) { - sysset("ps2", v = newstringobject("... ")); - XDECREF(v); - } - for (;;) { - ret = run_tty_1(fp, filename); -#ifdef REF_DEBUG - fprintf(stderr, "[%ld refs]\n", ref_total); -#endif - if (ret == E_EOF) - return 0; - /* - if (ret == E_NOMEM) - return -1; - */ - } -} - -int -run_tty_1(fp, filename) - FILE *fp; - char *filename; -{ - object *m, *d, *v, *w; - node *n; - char *ps1, *ps2; - int err; - v = sysget("ps1"); - w = sysget("ps2"); - if (v != NULL && is_stringobject(v)) { - INCREF(v); - ps1 = getstringvalue(v); - } - else { - v = NULL; - ps1 = ""; - } - if (w != NULL && is_stringobject(w)) { - INCREF(w); - ps2 = getstringvalue(w); - } - else { - w = NULL; - ps2 = ""; - } - err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n); - XDECREF(v); - XDECREF(w); - if (err == E_EOF) - return E_EOF; - if (err != E_DONE) { - err_input(err); - print_error(); - return err; - } - m = add_module("__main__"); - if (m == NULL) - return -1; - d = getmoduledict(m); - v = run_node(n, filename, d, d); - flushline(); - if (v == NULL) { - print_error(); - return -1; - } - DECREF(v); - return 0; -} - -int -run_script(fp, filename) - FILE *fp; - char *filename; -{ - object *m, *d, *v; - m = add_module("__main__"); - if (m == NULL) - return -1; - d = getmoduledict(m); - v = run_file(fp, filename, file_input, d, d); - flushline(); - if (v == NULL) { - print_error(); - return -1; - } - DECREF(v); - return 0; -} - -int -run_command(command) - char *command; -{ - object *m, *d, *v; - m = add_module("__main__"); - if (m == NULL) - return -1; - d = getmoduledict(m); - v = run_string(command, file_input, d, d); - flushline(); - if (v == NULL) { - print_error(); - return -1; - } - DECREF(v); - return 0; -} - -void -print_error() -{ - object *exception, *v; - err_get(&exception, &v); - if (exception == SystemExit) { - if (v == NULL || v == None) - goaway(0); - if (is_intobject(v)) - goaway((int)getintvalue(v)); - else { - printobject(v, stderr, PRINT_RAW); - fprintf(stderr, "\n"); - goaway(1); - } - } - sysset("last_type", exception); - sysset("last_value", v); - if (printobject(exception, stderr, PRINT_RAW) != 0) - err_clear(); - if (v != NULL && v != None) { - fprintf(stderr, ": "); - if (printobject(v, stderr, PRINT_RAW) != 0) - err_clear(); - } - fprintf(stderr, "\n"); - XDECREF(exception); - XDECREF(v); - printtraceback(stderr); -} - -object * -run_string(str, start, globals, locals) - char *str; - int start; - /*dict*/object *globals, *locals; -{ - node *n; - int err; - err = parse_string(str, start, &n); - return run_err_node(err, n, "<string>", globals, locals); -} - -object * -run_file(fp, filename, start, globals, locals) - FILE *fp; - char *filename; - int start; - /*dict*/object *globals, *locals; -{ - node *n; - int err; - err = parse_file(fp, filename, start, &n); - return run_err_node(err, n, filename, globals, locals); -} - -object * -run_err_node(err, n, filename, globals, locals) - int err; - node *n; - char *filename; - /*dict*/object *globals, *locals; -{ - if (err != E_DONE) { - err_input(err); - return NULL; - } - return run_node(n, filename, globals, locals); -} - -object * -run_node(n, filename, globals, locals) - node *n; - char *filename; - /*dict*/object *globals, *locals; -{ - if (globals == NULL) { - globals = getglobals(); - if (locals == NULL) - locals = getlocals(); - } - else { - if (locals == NULL) - locals = globals; - } - return eval_node(n, filename, globals, locals); -} - -object * -eval_node(n, filename, globals, locals) - node *n; - char *filename; - object *globals; - object *locals; -{ - codeobject *co; - object *v; - co = compile(n, filename); - freetree(n); - if (co == NULL) - return NULL; - v = eval_code(co, globals, locals, (object *)NULL); - DECREF(co); - return v; -} - -/* Simplified interface to parsefile */ - -int -parse_file(fp, filename, start, n_ret) - FILE *fp; - char *filename; - int start; - node **n_ret; -{ - return parsefile(fp, filename, &gram, start, - (char *)0, (char *)0, n_ret); -} - -/* Simplified interface to parsestring */ - -int -parse_string(str, start, n_ret) - char *str; - int start; - node **n_ret; -{ - int err = parsestring(str, &gram, start, n_ret); - /* Don't confuse early end of string with early end of input */ - if (err == E_EOF) - err = E_SYNTAX; - return err; -} - -/* Print fatal error message and abort */ - -void -fatal(msg) - char *msg; -{ - fprintf(stderr, "Fatal error: %s\n", msg); - abort(); -} - -/* Clean up and exit */ - -void -goaway(sts) - int sts; -{ - flushline(); - - /* XXX Call doneimport() before donecalls(), since donecalls() - calls wdone(), and doneimport() may close windows */ - doneimport(); - donecalls(); - - err_clear(); - -#ifdef REF_DEBUG - fprintf(stderr, "[%ld refs]\n", ref_total); -#endif - -#ifdef TRACE_REFS - if (askyesno("Print left references?")) { - printrefs(stderr); - } -#endif /* TRACE_REFS */ - - exit(sts); - /*NOTREACHED*/ -} - -#ifdef TRACE_REFS -/* Ask a yes/no question */ - -static int -askyesno(prompt) - char *prompt; -{ - char buf[256]; - - printf("%s [ny] ", prompt); - if (fgets(buf, sizeof buf, stdin) == NULL) - return 0; - return buf[0] == 'y' || buf[0] == 'Y'; -} -#endif - -#ifdef applec /* MPW (also usable for Think C 3.0) */ - -/* Check for file descriptor connected to interactive device. - Pretend that stdin is always interactive, other files never. */ - -int -isatty(fd) - int fd; -{ - return fd == fileno(stdin); -} - -#endif diff --git a/Python/pythonrun.c b/Python/pythonrun.c new file mode 100644 index 0000000..2a68f24 --- /dev/null +++ b/Python/pythonrun.c @@ -0,0 +1,424 @@ +/*********************************************************** +Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The +Netherlands. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Stichting Mathematisch +Centrum or CWI not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior permission. + +STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +******************************************************************/ + +/* Python interpreter top-level routines, including init/exit */ + +#include "allobjects.h" + +#include "grammar.h" +#include "node.h" +#include "parsetok.h" +#include "graminit.h" +#include "errcode.h" +#include "sysmodule.h" +#include "compile.h" +#include "ceval.h" +#include "pythonrun.h" +#include "import.h" + +#ifdef USE_THREAD +extern void *save_thread(); +#endif + +extern char *getpythonpath(); + +extern grammar gram; /* From graminit.c */ + +int debugging; /* Needed by parser.c */ +int verbose; /* Needed by import.c */ + +/* Initialize all */ + +void +initall() +{ + static int inited; + + if (inited) + return; + inited = 1; + + initimport(); + + /* Modules 'builtin' and 'sys' are initialized here, + they are needed by random bits of the interpreter. + All other modules are optional and are initialized + when they are first imported. */ + + initbuiltin(); /* Also initializes builtin exceptions */ + initsys(); + + initcalls(); /* Configuration-dependent initializations */ + + initintr(); /* For intrcheck() */ + + setpythonpath(getpythonpath()); +} + +/* Parse input from a file and execute it */ + +int +run(fp, filename) + FILE *fp; + char *filename; +{ + if (filename == NULL) + filename = "???"; + if (isatty((int)fileno(fp))) + return run_tty_loop(fp, filename); + else + return run_script(fp, filename); +} + +int +run_tty_loop(fp, filename) + FILE *fp; + char *filename; +{ + object *v; + int ret; + v = sysget("ps1"); + if (v == NULL) { + sysset("ps1", v = newstringobject(">>> ")); + XDECREF(v); + } + v = sysget("ps2"); + if (v == NULL) { + sysset("ps2", v = newstringobject("... ")); + XDECREF(v); + } + for (;;) { + ret = run_tty_1(fp, filename); +#ifdef REF_DEBUG + fprintf(stderr, "[%ld refs]\n", ref_total); +#endif + if (ret == E_EOF) + return 0; + /* + if (ret == E_NOMEM) + return -1; + */ + } +} + +int +run_tty_1(fp, filename) + FILE *fp; + char *filename; +{ + void *save, *save_thread(), restore_thread(); + object *m, *d, *v, *w; + node *n; + char *ps1, *ps2; + int err; + v = sysget("ps1"); + w = sysget("ps2"); + if (v != NULL && is_stringobject(v)) { + INCREF(v); + ps1 = getstringvalue(v); + } + else { + v = NULL; + ps1 = ""; + } + if (w != NULL && is_stringobject(w)) { + INCREF(w); + ps2 = getstringvalue(w); + } + else { + w = NULL; + ps2 = ""; + } + save = save_thread(); + err = parsefile(fp, filename, &gram, single_input, ps1, ps2, &n); + restore_thread(save); + XDECREF(v); + XDECREF(w); + if (err == E_EOF) + return E_EOF; + if (err != E_DONE) { + err_input(err); + print_error(); + return err; + } + m = add_module("__main__"); + if (m == NULL) + return -1; + d = getmoduledict(m); + v = run_node(n, filename, d, d); + flushline(); + if (v == NULL) { + print_error(); + return -1; + } + DECREF(v); + return 0; +} + +int +run_script(fp, filename) + FILE *fp; + char *filename; +{ + object *m, *d, *v; + m = add_module("__main__"); + if (m == NULL) + return -1; + d = getmoduledict(m); + v = run_file(fp, filename, file_input, d, d); + flushline(); + if (v == NULL) { + print_error(); + return -1; + } + DECREF(v); + return 0; +} + +int +run_command(command) + char *command; +{ + object *m, *d, *v; + m = add_module("__main__"); + if (m == NULL) + return -1; + d = getmoduledict(m); + v = run_string(command, file_input, d, d); + flushline(); + if (v == NULL) { + print_error(); + return -1; + } + DECREF(v); + return 0; +} + +void +print_error() +{ + object *exception, *v; + err_get(&exception, &v); + if (exception == SystemExit) { + if (v == NULL || v == None) + goaway(0); + if (is_intobject(v)) + goaway((int)getintvalue(v)); + else { + printobject(v, stderr, PRINT_RAW); + fprintf(stderr, "\n"); + goaway(1); + } + } + sysset("last_type", exception); + sysset("last_value", v); + if (printobject(exception, stderr, PRINT_RAW) != 0) + err_clear(); + if (v != NULL && v != None) { + fprintf(stderr, ": "); + if (printobject(v, stderr, PRINT_RAW) != 0) + err_clear(); + } + fprintf(stderr, "\n"); + XDECREF(exception); + XDECREF(v); + printtraceback(stderr); +} + +object * +run_string(str, start, globals, locals) + char *str; + int start; + /*dict*/object *globals, *locals; +{ + node *n; + int err; + err = parse_string(str, start, &n); + return run_err_node(err, n, "<string>", globals, locals); +} + +object * +run_file(fp, filename, start, globals, locals) + FILE *fp; + char *filename; + int start; + /*dict*/object *globals, *locals; +{ + node *n; + int err; + err = parse_file(fp, filename, start, &n); + return run_err_node(err, n, filename, globals, locals); +} + +object * +run_err_node(err, n, filename, globals, locals) + int err; + node *n; + char *filename; + /*dict*/object *globals, *locals; +{ + if (err != E_DONE) { + err_input(err); + return NULL; + } + return run_node(n, filename, globals, locals); +} + +object * +run_node(n, filename, globals, locals) + node *n; + char *filename; + /*dict*/object *globals, *locals; +{ + if (globals == NULL) { + globals = getglobals(); + if (locals == NULL) + locals = getlocals(); + } + else { + if (locals == NULL) + locals = globals; + } + return eval_node(n, filename, globals, locals); +} + +object * +eval_node(n, filename, globals, locals) + node *n; + char *filename; + object *globals; + object *locals; +{ + codeobject *co; + object *v; + co = compile(n, filename); + freetree(n); + if (co == NULL) + return NULL; + v = eval_code(co, globals, locals, (object *)NULL); + DECREF(co); + return v; +} + +/* Simplified interface to parsefile */ + +int +parse_file(fp, filename, start, n_ret) + FILE *fp; + char *filename; + int start; + node **n_ret; +{ + return parsefile(fp, filename, &gram, start, + (char *)0, (char *)0, n_ret); +} + +/* Simplified interface to parsestring */ + +int +parse_string(str, start, n_ret) + char *str; + int start; + node **n_ret; +{ + int err = parsestring(str, &gram, start, n_ret); + /* Don't confuse early end of string with early end of input */ + if (err == E_EOF) + err = E_SYNTAX; + return err; +} + +/* Print fatal error message and abort */ + +void +fatal(msg) + char *msg; +{ + fprintf(stderr, "Fatal error: %s\n", msg); + abort(); +} + +/* Clean up and exit */ + +void +goaway(sts) + int sts; +{ + flushline(); + + /* XXX Call doneimport() before donecalls(), since donecalls() + calls wdone(), and doneimport() may close windows */ + doneimport(); + donecalls(); + + err_clear(); + +#ifdef REF_DEBUG + fprintf(stderr, "[%ld refs]\n", ref_total); +#endif + +#ifdef TRACE_REFS + if (askyesno("Print left references?")) { + printrefs(stderr); + } +#endif /* TRACE_REFS */ + +#ifdef USE_THREAD + (void) save_thread(); + exit_prog(sts); +#else + exit(sts); +#endif + /*NOTREACHED*/ +} + +#ifdef TRACE_REFS +/* Ask a yes/no question */ + +static int +askyesno(prompt) + char *prompt; +{ + char buf[256]; + + printf("%s [ny] ", prompt); + if (fgets(buf, sizeof buf, stdin) == NULL) + return 0; + return buf[0] == 'y' || buf[0] == 'Y'; +} +#endif + +#ifdef applec /* MPW (also usable for Think C 3.0) */ + +/* Check for file descriptor connected to interactive device. + Pretend that stdin is always interactive, other files never. */ + +int +isatty(fd) + int fd; +{ + return fd == fileno(stdin); +} + +#endif diff --git a/Python/thread.c b/Python/thread.c new file mode 100644 index 0000000..1f0633a --- /dev/null +++ b/Python/thread.c @@ -0,0 +1,263 @@ +#include "thread.h" + +#ifdef __sgi +#include <stdlib.h> +#include <stdio.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/prctl.h> +#include <ulocks.h> + +static usptr_t *shared_arena; +static int exit_status; +static int do_exit; +static int exiting; +#endif +#ifdef sun +#include <lwp/lwp.h> +#include <lwp/stackdep.h> + +#define STACKSIZE 1000 /* stacksize for a thread */ +#define NSTACKS 2 /* # stacks to be put in cache initialy */ + +struct lock { + int lock_locked; + cv_t lock_condvar; + mon_t lock_monitor; +}; +#endif +#ifdef C_THREADS +#include <cthreads.h> +#endif + +#ifdef __STDC__ +#define _P(args) args +#define _P0() (void) +#define _P1(v,t) (t) +#define _P2(v1,t1,v2,t2) (t1,t2) +#else +#define _P(args) () +#define _P0() () +#define _P1(v,t) (v) t; +#define _P2(v1,t1,v2,t2) (v1,v2) t1; t2; +#endif + +static int initialized; + +int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) +{ +#ifdef sun + thread_t tid; +#endif +#ifdef DEBUG + printf("start_new_thread called\n"); +#endif + if (!initialized) + init_thread(); +#ifdef __sgi + if (sproc(func, PR_SALL, arg) < 0) + return 0; + return 1; +#endif +#ifdef SOLARIS + (void) thread_create(0, 0, func, arg, THREAD_NEW_LWP); +#endif +#ifdef sun + if (lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg) < 0) + return 0; + return 1; +#endif +#ifdef C_THREADS + (void) cthread_fork(func, arg); +#endif +} + +#ifdef __sgi +void maybe_exit _P0() +{ + if (exiting) + return; + exit_prog(0); +} +#endif + +void exit_thread _P0() +{ +#ifdef DEBUG + printf("exit_thread called\n"); +#endif + if (!initialized) + exit(0); +#ifdef __sgi + exiting = 1; + exit(0); +#endif +#ifdef SOLARIS + thread_exit(); +#endif +#ifdef sun + lwp_destroy(SELF); +#endif +#ifdef C_THREADS + cthread_exit(0); +#endif +} + +#ifdef __sgi +static void exit_sig _P0() +{ +#ifdef DEBUG + printf("exit_sig called\n"); +#endif + if (do_exit) { +#ifdef DEBUG + printf("exiting in exit_sig\n"); +#endif + exit(exit_status); + } +} +#endif + +void init_thread _P0() +{ +#ifdef __sgi + struct sigaction s; +#endif + +#ifdef DEBUG + printf("init_thread called\n"); +#endif + initialized = 1; + +#ifdef __sgi + atexit(maybe_exit); + s.sa_handler = exit_sig; + sigemptyset(&s.sa_mask); + sigaddset(&s.sa_mask, SIGUSR1); + s.sa_flags = 0; + sigaction(SIGUSR1, &s, 0); + prctl(PR_SETEXITSIG, SIGUSR1); + usconfig(CONF_ARENATYPE, US_SHAREDONLY); + /*usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);*/ + shared_arena = usinit(tmpnam(0)); +#endif +#ifdef sun + lwp_setstkcache(STACKSIZE, NSTACKS); +#endif +#ifdef C_THREADS + cthread_init(); +#endif +} + +type_lock allocate_lock _P0() +{ +#ifdef __sgi + ulock_t lock; +#endif +#ifdef sun + struct lock *lock; + extern char *malloc(); +#endif + +#ifdef DEBUG + printf("allocate_lock called\n"); +#endif + if (!initialized) + init_thread(); + +#ifdef __sgi + lock = usnewlock(shared_arena); + (void) usinitlock(lock); +#endif +#ifdef sun + lock = (struct lock *) malloc(sizeof(struct lock)); + lock->lock_locked = 0; + (void) mon_create(&lock->lock_monitor); + (void) cv_create(&lock->lock_condvar, lock->lock_monitor); +#endif +#ifdef DEBUG + printf("allocate_lock() -> %lx\n", (long)lock); +#endif + return (type_lock) lock; +} + +void free_lock _P1(lock, type_lock lock) +{ +#ifdef DEBUG + printf("free_lock(%lx) called\n", (long)lock); +#endif +#ifdef __sgi + usfreelock((ulock_t) lock, shared_arena); +#endif +#ifdef sun + mon_destroy(((struct lock *) lock)->lock_monitor); + free((char *) lock); +#endif +} + +int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag) +{ + int success; + +#ifdef DEBUG + printf("acquire_lock(%lx, %d) called\n", (long)lock, waitflag); +#endif +#ifdef __sgi + if (waitflag) + success = ussetlock((ulock_t) lock); + else + success = uscsetlock((ulock_t) lock, 1); /* Try it once */ +#endif +#ifdef sun + success = 0; + + (void) mon_enter(((struct lock *) lock)->lock_monitor); + if (waitflag) + while (((struct lock *) lock)->lock_locked) + cv_wait(((struct lock *) lock)->lock_condvar); + if (!((struct lock *) lock)->lock_locked) { + success = 1; + ((struct lock *) lock)->lock_locked = 1; + } + cv_broadcast(((struct lock *) lock)->lock_condvar); + mon_exit(((struct lock *) lock)->lock_monitor); +#endif +#ifdef DEBUG + printf("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success); +#endif + return success; +} + +void release_lock _P1(lock, type_lock lock) +{ +#ifdef DEBUG + printf("release lock(%lx) called\n", (long)lock); +#endif +#ifdef __sgi + (void) usunsetlock((ulock_t) lock); +#endif +#ifdef sun + (void) mon_enter(((struct lock *) lock)->lock_monitor); + ((struct lock *) lock)->lock_locked = 0; + cv_broadcast(((struct lock *) lock)->lock_condvar); + mon_exit(((struct lock *) lock)->lock_monitor); +#endif +} + +void exit_prog _P1(status, int status) +{ +#ifdef DEBUG + printf("exit_prog(%d) called\n", status); +#endif + if (!initialized) + exit(status); +#ifdef __sgi + exiting = 1; + do_exit = 1; + exit_status = status; + exit(status); +#endif +#ifdef sun + pod_exit(status); +#endif +} |