thread_lwp.h revision cf1474b73ad3e4085af220f3845b75b201974d38
1/*********************************************************** 2Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam, 3The Netherlands. 4 5 All Rights Reserved 6 7Permission to use, copy, modify, and distribute this software and its 8documentation for any purpose and without fee is hereby granted, 9provided that the above copyright notice appear in all copies and that 10both that copyright notice and this permission notice appear in 11supporting documentation, and that the names of Stichting Mathematisch 12Centrum or CWI not be used in advertising or publicity pertaining to 13distribution of the software without specific, written prior permission. 14 15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO 16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE 18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 22 23******************************************************************/ 24 25#include <stdlib.h> 26#include <lwp/lwp.h> 27#include <lwp/stackdep.h> 28 29#define STACKSIZE 1000 /* stacksize for a thread */ 30#define NSTACKS 2 /* # stacks to be put in cache initialy */ 31 32struct lock { 33 int lock_locked; 34 cv_t lock_condvar; 35 mon_t lock_monitor; 36}; 37 38 39/* 40 * Initialization. 41 */ 42static void _init_thread _P0() 43{ 44 lwp_setstkcache(STACKSIZE, NSTACKS); 45} 46 47/* 48 * Thread support. 49 */ 50 51 52int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg) 53{ 54 thread_t tid; 55 int success; 56 dprintf(("start_new_thread called\n")); 57 if (!initialized) 58 init_thread(); 59 success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg); 60 return success < 0 ? 0 : 1; 61} 62 63long get_thread_ident _P0() 64{ 65 thread_t tid; 66 if (!initialized) 67 init_thread(); 68 if (lwp_self(&tid) < 0) 69 return -1; 70 return tid.thread_id; 71} 72 73static void do_exit_thread _P1(no_cleanup, int no_cleanup) 74{ 75 dprintf(("exit_thread called\n")); 76 if (!initialized) 77 if (no_cleanup) 78 _exit(0); 79 else 80 exit(0); 81 lwp_destroy(SELF); 82} 83 84void exit_thread _P0() 85{ 86 do_exit_thread(0); 87} 88 89void _exit_thread _P0() 90{ 91 do_exit_thread(1); 92} 93 94#ifndef NO_EXIT_PROG 95static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup) 96{ 97 dprintf(("exit_prog(%d) called\n", status)); 98 if (!initialized) 99 if (no_cleanup) 100 _exit(status); 101 else 102 exit(status); 103 pod_exit(status); 104} 105 106void exit_prog _P1(status, int status) 107{ 108 do_exit_prog(status, 0); 109} 110 111void _exit_prog _P1(status, int status) 112{ 113 do_exit_prog(status, 1); 114} 115#endif /* NO_EXIT_PROG */ 116 117/* 118 * Lock support. 119 */ 120type_lock allocate_lock _P0() 121{ 122 struct lock *lock; 123 extern char *malloc(); 124 125 dprintf(("allocate_lock called\n")); 126 if (!initialized) 127 init_thread(); 128 129 lock = (struct lock *) malloc(sizeof(struct lock)); 130 lock->lock_locked = 0; 131 (void) mon_create(&lock->lock_monitor); 132 (void) cv_create(&lock->lock_condvar, lock->lock_monitor); 133 dprintf(("allocate_lock() -> %lx\n", (long)lock)); 134 return (type_lock) lock; 135} 136 137void free_lock _P1(lock, type_lock lock) 138{ 139 dprintf(("free_lock(%lx) called\n", (long)lock)); 140 mon_destroy(((struct lock *) lock)->lock_monitor); 141 free((char *) lock); 142} 143 144int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag) 145{ 146 int success; 147 148 dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag)); 149 success = 0; 150 151 (void) mon_enter(((struct lock *) lock)->lock_monitor); 152 if (waitflag) 153 while (((struct lock *) lock)->lock_locked) 154 cv_wait(((struct lock *) lock)->lock_condvar); 155 if (!((struct lock *) lock)->lock_locked) { 156 success = 1; 157 ((struct lock *) lock)->lock_locked = 1; 158 } 159 cv_broadcast(((struct lock *) lock)->lock_condvar); 160 mon_exit(((struct lock *) lock)->lock_monitor); 161 dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success)); 162 return success; 163} 164 165void release_lock _P1(lock, type_lock lock) 166{ 167 dprintf(("release_lock(%lx) called\n", (long)lock)); 168 (void) mon_enter(((struct lock *) lock)->lock_monitor); 169 ((struct lock *) lock)->lock_locked = 0; 170 cv_broadcast(((struct lock *) lock)->lock_condvar); 171 mon_exit(((struct lock *) lock)->lock_monitor); 172} 173 174/* 175 * Semaphore support. 176 */ 177type_sema allocate_sema _P1(value, int value) 178{ 179 type_sema sema = 0; 180 dprintf(("allocate_sema called\n")); 181 if (!initialized) 182 init_thread(); 183 184 dprintf(("allocate_sema() -> %lx\n", (long) sema)); 185 return (type_sema) sema; 186} 187 188void free_sema _P1(sema, type_sema sema) 189{ 190 dprintf(("free_sema(%lx) called\n", (long) sema)); 191} 192 193int down_sema _P2(sema, type_sema sema, waitflag, int waitflag) 194{ 195 dprintf(("down_sema(%lx, %d) called\n", (long) sema, waitflag)); 196 dprintf(("down_sema(%lx) return\n", (long) sema)); 197 return -1; 198} 199 200void up_sema _P1(sema, type_sema sema) 201{ 202 dprintf(("up_sema(%lx)\n", (long) sema)); 203} 204