]> gcc.gnu.org Git - gcc.git/blame - libchill/waitbuffer.c
gjavah.c (java_no_argument): Renamed from no_argument to avoid losing due to namespac...
[gcc.git] / libchill / waitbuffer.c
CommitLineData
b79f73df
JL
1/* Implement tasking-related runtime actions for CHILL.
2 Copyright (C) 1992,1993 Free Software Foundation, Inc.
3 Author: Wilfried Moser
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 2, or (at your option)
10any later version.
11
12GNU CC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU CC; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21#include "rtltypes.h"
22#include "rts.h"
23
24extern void __cause_ex1 (char *ex, char *file, int lineno);
25
26EXCEPTION (bufferinconsistency)
27#define CAUSE_BUFFINCONS __cause_ex1 ("bufferinconsistency", filename, lineno)
28EXCEPTION (spacefail);
29#define CAUSE_SPACEFAIL __cause_ex1 ("spacefail", filename, lineno)
30
31/*
32 * function __wait_buffer
33 *
34 * parameters:
35 * buf_got pointer to location for writing the received buffer address
36 * nbuf number of buffers in RECEIVE CASE
37 * bufptr array of pointers to buffer descriptor
38 * datap pointer where to store data
39 * datalen length of data
40 * ins pointer to instance location or 0
41 * else_clause else specified or not
42 * to_loc pointer to timesupervision value
43 * filename source file name where function gets called
44 * lineno linenumber in source file
45 *
46 * returns:
47 * int 0 .. success
48 * 1 .. timed out
49 *
50 * exceptions:
51 * bufferinconsistency if something's wrong in the buffer queue's
52 * spacefail out of heap space of datalength of receiver
53 * less then data avilable.
54 *
55 * abstract:
56 * implement the CHILL RECEIVE buffer CASE action.
57 */
58
59int
60__wait_buffer (buf_got, nbuf, bufptr, datap, datalen, ins,
61 else_clause, to, filename, lineno)
62 void **buf_got;
63 int nbuf;
64 Buffer_Descr *bufptr[];
65 void *datap;
66 int datalen;
67 INSTANCE *ins;
68 int else_clause;
69 void *to;
70 char *filename;
71 int lineno;
72{
73 int i;
74 Buffer_Wait_Queue *start_list;
75 Buffer_Queue **retval;
76 Buffer_Queue **highprio;
77 int timed_out;
78
79 /* look if there is a buffer already sent */
80 highprio = 0;
81 for (i = 0; i < nbuf; i++)
82 {
83 Buffer_Queue *bq;
84
85 memcpy (&bq, bufptr[i]->buf, sizeof (Buffer_Queue *));
86 if (bq != 0 && bq->sendqueue != 0)
87 {
88 if (highprio != 0)
89 {
90 Buffer_Queue *bsq = *highprio;
91
92 if (bq->sendqueue->priority > bsq->sendqueue->priority)
93 highprio = bufptr[i]->buf;
94 }
95 else
96 highprio = bufptr[i]->buf;
97 }
98 }
99
100 if (highprio != 0)
101 {
102 Buffer_Queue *bq;
103
104 memcpy (&bq, highprio, sizeof (Buffer_Queue *));
105 if (bq != 0 && bq->sendqueue != 0)
106 {
107 Buffer_Send_Queue *bsq = bq->sendqueue;
108 Buffer_Send_Queue *tmp;
109
110 /* check data length */
111 if (datalen < bsq->datalen)
112 /* something's totaly wrong. Raise exception */
113 CAUSE_SPACEFAIL;
114
115 /* copy data out */
116 memcpy (datap, bsq->dataptr, bsq->datalen);
117
118 /* update instance, if present */
119 if (ins != 0)
120 memcpy (ins, &bsq->this, sizeof (INSTANCE));
121
122 /* dequeue entry */
123 tmp = bsq;
124 bq->sendqueue = tmp->forward;
125
126 if (tmp->is_delayed)
127 {
128 /* there is an instance delayed on a send,
129 continue it. */
130 __continue_that (tmp->this, tmp->priority, filename, lineno);
131 FREE (tmp);
132
133 /* return the buffer we have received from */
134 *buf_got = (void *)highprio;
135 return 0;
136 }
137
138 /* just decrease sendqueue length */
139 bq->sendqueuelength--;
140
141 FREE (tmp);
142
143 /* as we got an entry free, we should continue
144 an INSTANCE which is delayed on a send at this
145 buffer */
146 bsq = bq->sendqueue;
147 while (bsq != 0)
148 {
149 if (bsq->is_delayed)
150 {
151 bq->sendqueuelength++;
152 bsq->is_delayed = 0;
153 __continue_that (bsq->this, bsq->priority, filename, lineno);
154 break;
155 }
156 bsq = bsq->forward;
157 }
158 /* return the buffer we have received from */
159 *buf_got = (void *)highprio;
160 return 0;
161 }
162 }
163
164 /* if we come here, there is no buffer already sent */
165 if (else_clause != 0)
166 {
167 /* in that case we return immediately */
168 *buf_got = 0;
169 return 0;
170 }
171
172 /* now we have to queue ourself to the wait queue(s) */
173 start_list = 0;
174 for (i = 0; i < nbuf; i++)
175 {
176 Buffer_Queue *bq;
177 Buffer_Wait_Queue *wrk;
178 Buffer_Wait_Queue *bwq;
179 Buffer_Wait_Queue *prev_queue_entry = 0;
180 Buffer_Wait_Queue *prev_list_entry;
181 int j, have_done = 0;
182
183 for (j = 0; j < i; j++)
184 {
185 if (bufptr[i]->buf == bufptr[j]->buf)
186 {
187 have_done = 1;
188 break;
189 }
190 }
191 if (have_done)
192 continue;
193
194 memcpy (&bq, bufptr[i]->buf, sizeof (Buffer_Queue *));
195 if (bq == 0)
196 {
197 MALLOC (bq, sizeof (Buffer_Queue));
198 memset (bq, 0, sizeof (Buffer_Queue));
199 /* *(bufptr[i]->buf) = bq; may be unaligned */
200 memcpy (bufptr[i]->buf, &bq, sizeof (Buffer_Queue *));
201 }
202 MALLOC (wrk, sizeof (Buffer_Wait_Queue));
203 memset (wrk, 0, sizeof (Buffer_Wait_Queue));
204 bwq = (Buffer_Wait_Queue *)&bq->waitqueue;
205
206 wrk->this = THIS;
207 wrk->datalen = datalen;
208 wrk->dataptr = datap;
209 wrk->bufferaddr = bufptr[i]->buf;
210
211 /* queue it at the end of buffer wait queue */
212 while (bwq->forward != 0)
213 bwq = bwq->forward;
214 wrk->forward = bwq->forward;
215 bwq->forward = wrk;
216
217 /* queue it into list */
218 wrk->startlist = start_list;
219 if (! start_list)
220 {
221 start_list = wrk;
222 prev_list_entry = wrk;
223 wrk->startlist = start_list;
224 }
225 else
226 {
227 prev_list_entry->chain = wrk;
228 prev_list_entry = wrk;
229 }
230
231 /* increment wait queue count */
232 bq->waitqueuelength++;
233 }
234
235 /* tell runtime system to delay this process */
236 timed_out = __delay_this (wait_buffer_receive, to, filename, lineno);
237 if (timed_out)
238 {
239 /* remove all entries from buffer queues */
240 Buffer_Wait_Queue *listentry = start_list;
241
242 while (listentry != 0)
243 {
244 Buffer_Queue *bq = *(listentry->bufferaddr);
245 Buffer_Wait_Queue *prev_entry = (Buffer_Wait_Queue *)&bq->waitqueue;
246 Buffer_Wait_Queue *bwq = bq->waitqueue;
247
248 while (bwq != listentry)
249 {
250 prev_entry = bwq;
251 bwq = bwq->forward;
252 }
253 /* dequeue it */
254 prev_entry->forward = bwq->forward;
255 bq->waitqueuelength--;
256 listentry = listentry->chain;
257 }
258 }
259
260 /* someone has continued us, find which buffer got ready */
261 retval = 0;
262
263 while (start_list != 0)
264 {
265 Buffer_Wait_Queue *tmp = start_list->chain;
266
267 if (start_list->is_sent)
268 {
269 /* this one has been sent */
270 /* save return value */
271 if (retval == 0)
272 retval = start_list->bufferaddr;
273 else
274 /* more then one has been sent, that's wrong */
275 CAUSE_BUFFINCONS;
276
277 /* update instance, if present */
278 if (ins != 0)
279 memcpy (ins, &start_list->who_sent, sizeof (INSTANCE));
280 }
281 FREE (start_list);
282 start_list = tmp;
283 }
284
285 /* now check if there was really a buffer got */
286 if (retval == 0 && !timed_out)
287 /* something's totally wrong, raise an exception */
288 CAUSE_BUFFINCONS;
289
290 if (!timed_out)
291 *buf_got = (void *)retval;
292 return timed_out;
293}
294
295/* force function __print_buffer to be linked */
296extern void __print_buffer ();
297static EntryPoint pev = __print_buffer;
This page took 0.496819 seconds and 5 git commands to generate.