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/thread.c | |
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/thread.c')
-rw-r--r-- | Python/thread.c | 263 |
1 files changed, 263 insertions, 0 deletions
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 +} |