Thu Nov 5 07:57:45 EST 1998 Andrew MacLeod <amacleod@cygnus.com>
[official-gcc.git] / libchill / delaycase.c
blob299ec9b90d1a0c6d030c2be59bf937cae62af35c
1 /* Implement tasking-related runtime actions for CHILL.
2 Copyright (C) 1992,1993 Free Software Foundation, Inc.
3 Author: Wilfried Moser
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* As a special exception, if you link this library with other files,
22 some of which are compiled with GCC, to produce an executable,
23 this library does not by itself cause the resulting executable
24 to be covered by the GNU General Public License.
25 This exception does not however invalidate any other reasons why
26 the executable file might be covered by the GNU General Public License. */
28 #include "rtltypes.h"
29 #include "rts.h"
31 extern void __cause_ex1 (char *ex, char *file, int lineno);
33 EXCEPTION (delayfail);
34 #define CAUSE_DELAYFAIL __cause_ex1 ("delayfail", filename, lineno)
36 EXCEPTION (notyetimplemented);
37 #define CAUSE_NOTIMPLEMENTED __cause_ex1 ("notyetimplemeyed", filename, lineno)
40 * function __delay_event
42 * parameters:
43 * ev_got pointer to location where to write the event got.
44 * nevents number of events in list
45 * evptrs array of event descriptors
46 * priority specified priority
47 * insloc pointer to resulting instance location
48 * to timeout value
49 * filename filename of caller
50 * lineno linenumber of caller
52 * returns:
53 * int 0 .. success
54 * 1 .. timed out
56 * exceptions:
57 * delayfail
59 * abstract:
60 * implement the CHILL DELAY and DELAY CASE actions.
64 int
65 __delay_event (ev_got, nevents, evptrs, priority, to, insloc, filename, lineno)
66 void **ev_got;
67 int nevents;
68 Event_Descr *evptrs;
69 int priority;
70 void *to;
71 INSTANCE *insloc;
72 char *filename;
73 int lineno;
75 int i, already_done = 0;
76 Event_Queue *start_list = 0;
77 Event_Queue **retval = 0;
78 Event_Queue *wrk;
79 int timed_out = 0;
81 /* check if all specified event queues have enough space left
82 to perform the delay */
83 for (i = 0; i < nevents; i++)
85 Event_Queue *e;
86 unsigned long cnt = 0;
87 int j, have_done = 0;
89 if (evptrs[i].maxqueuelength == 0)
90 CAUSE_DELAYFAIL;
91 else if (evptrs[i].maxqueuelength == (unsigned long)-1L)
92 /* infinite length */
93 continue;
95 /* check if we already have processed this one, that means, this
96 event is mentioned more then once */
97 for (j = 0; j < i; j++)
99 if (evptrs[i].ev == evptrs[j].ev)
101 have_done = 1;
102 break;
105 if (have_done)
106 continue;
108 memcpy (&e, evptrs[i].ev, sizeof (Event_Queue *));
109 while (e)
111 cnt++;
112 e = e->forward;
114 if (cnt >= evptrs[i].maxqueuelength)
115 CAUSE_DELAYFAIL;
118 for (i = 0; i < nevents; i++)
120 /* queue that stuff on each event */
121 Event_Queue *wrk;
122 Event_Queue *ev;
123 Event_Queue *prev_queue_entry = 0;
124 Event_Queue *prev_list_entry;
125 int j, have_done = 0;
127 /* check for this event already processed */
128 for (j = 0; j < i; j++)
130 if (evptrs[i].ev == evptrs[j].ev)
132 have_done = 1;
133 break;
136 if (have_done)
137 continue;
139 memcpy (&ev, &evptrs[i].ev, sizeof (Event_Queue *));
140 MALLOC (wrk, sizeof (Event_Queue));
141 memset (wrk, 0, sizeof (Event_Queue));
143 wrk->priority = priority;
144 wrk->this = THIS;
145 wrk->listhead = evptrs[i].ev;
147 /* search for the place to queue this entry in */
148 while (ev->forward != 0 && ev->priority >= priority)
150 prev_queue_entry = ev;
151 ev = ev->forward;
154 /* ready to put entry into queue */
155 if (ev->forward == 0 || prev_queue_entry == 0)
157 /* beginning or end of the list */
158 wrk->forward = ev->forward;
159 ev->forward = wrk;
161 else
163 /* this is somewhere in the middle */
164 wrk->forward = prev_queue_entry->forward;
165 prev_queue_entry->forward = wrk;
168 /* queue it into list */
169 wrk->startlist = start_list;
170 if (! start_list)
172 /* we are the first in the list */
173 start_list = wrk;
174 prev_list_entry = wrk;
175 wrk->startlist = start_list;
177 else
179 prev_list_entry->chain = wrk;
180 prev_list_entry = wrk;
184 /* tell runtime system to delay that process */
185 timed_out = __delay_this (wait_event_delay, to, filename, lineno);
186 if (timed_out)
188 /* we have to remove the entries from the queue's */
189 wrk = start_list;
190 while (wrk)
192 Event_Queue *tmp = (Event_Queue *)wrk->listhead;
194 while (tmp->forward != wrk)
195 tmp = tmp->forward;
196 tmp->forward = wrk->forward;
197 wrk = wrk->chain;
201 wrk = start_list;
202 while (wrk)
204 Event_Queue *tmp;
206 if (wrk->is_continued && ! already_done)
208 already_done = 1;
209 retval = wrk->listhead;
210 if (insloc && !timed_out)
212 insloc->ptype = wrk->who_continued.ptype;
213 insloc->pcopy = wrk->who_continued.pcopy;
216 tmp = wrk->chain;
217 FREE (wrk);
218 wrk = tmp;
220 if (!timed_out && ev_got)
221 *ev_got = (void *)retval;
222 return timed_out;
225 /* force function print_event to be linked */
226 extern void __print_event ();
227 static EntryPoint pev = __print_event;