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