Make sure THEN block has any insns at before testing for indirect jump
[official-gcc.git] / libchill / delaycase.c
blob3c2a3c7777adfeb16d35583e9eb44336d6cf5a5c
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, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
29 #include <string.h>
30 #include "rtltypes.h"
31 #include "rts.h"
33 extern void __cause_ex1 (char *ex, char *file, int lineno);
35 EXCEPTION (delayfail);
36 #define CAUSE_DELAYFAIL __cause_ex1 ("delayfail", filename, lineno)
38 EXCEPTION (notyetimplemented);
39 #define CAUSE_NOTIMPLEMENTED __cause_ex1 ("notyetimplemeyed", filename, lineno)
42 * function __delay_event
44 * parameters:
45 * ev_got pointer to location where to write the event got.
46 * nevents number of events in list
47 * evptrs array of event descriptors
48 * priority specified priority
49 * insloc pointer to resulting instance location
50 * to timeout value
51 * filename filename of caller
52 * lineno linenumber of caller
54 * returns:
55 * int 0 .. success
56 * 1 .. timed out
58 * exceptions:
59 * delayfail
61 * abstract:
62 * implement the CHILL DELAY and DELAY CASE actions.
66 int
67 __delay_event (ev_got, nevents, evptrs, priority, to, insloc, filename, lineno)
68 void **ev_got;
69 int nevents;
70 Event_Descr *evptrs;
71 int priority;
72 void *to;
73 INSTANCE *insloc;
74 char *filename;
75 int lineno;
77 int i, already_done = 0;
78 Event_Queue *start_list = 0;
79 Event_Queue **retval = 0;
80 Event_Queue *wrk;
81 int timed_out = 0;
83 /* check if all specified event queues have enough space left
84 to perform the delay */
85 for (i = 0; i < nevents; i++)
87 Event_Queue *e;
88 unsigned long cnt = 0;
89 int j, have_done = 0;
91 if (evptrs[i].maxqueuelength == 0)
92 CAUSE_DELAYFAIL;
93 else if (evptrs[i].maxqueuelength == (unsigned long)-1L)
94 /* infinite length */
95 continue;
97 /* check if we already have processed this one, that means, this
98 event is mentioned more then once */
99 for (j = 0; j < i; j++)
101 if (evptrs[i].ev == evptrs[j].ev)
103 have_done = 1;
104 break;
107 if (have_done)
108 continue;
110 memcpy (&e, evptrs[i].ev, sizeof (Event_Queue *));
111 while (e)
113 cnt++;
114 e = e->forward;
116 if (cnt >= evptrs[i].maxqueuelength)
117 CAUSE_DELAYFAIL;
120 for (i = 0; i < nevents; i++)
122 /* queue that stuff on each event */
123 Event_Queue *wrk;
124 Event_Queue *ev;
125 Event_Queue *prev_queue_entry = 0;
126 Event_Queue *prev_list_entry;
127 int j, have_done = 0;
129 /* check for this event already processed */
130 for (j = 0; j < i; j++)
132 if (evptrs[i].ev == evptrs[j].ev)
134 have_done = 1;
135 break;
138 if (have_done)
139 continue;
141 memcpy (&ev, &evptrs[i].ev, sizeof (Event_Queue *));
142 MALLOC (wrk, sizeof (Event_Queue));
143 memset (wrk, 0, sizeof (Event_Queue));
145 wrk->priority = priority;
146 wrk->this = THIS;
147 wrk->listhead = evptrs[i].ev;
149 /* search for the place to queue this entry in */
150 while (ev->forward != 0 && ev->priority >= priority)
152 prev_queue_entry = ev;
153 ev = ev->forward;
156 /* ready to put entry into queue */
157 if (ev->forward == 0 || prev_queue_entry == 0)
159 /* beginning or end of the list */
160 wrk->forward = ev->forward;
161 ev->forward = wrk;
163 else
165 /* this is somewhere in the middle */
166 wrk->forward = prev_queue_entry->forward;
167 prev_queue_entry->forward = wrk;
170 /* queue it into list */
171 wrk->startlist = start_list;
172 if (! start_list)
174 /* we are the first in the list */
175 start_list = wrk;
176 prev_list_entry = wrk;
177 wrk->startlist = start_list;
179 else
181 prev_list_entry->chain = wrk;
182 prev_list_entry = wrk;
186 /* tell runtime system to delay that process */
187 timed_out = __delay_this (wait_event_delay, to, filename, lineno);
188 if (timed_out)
190 /* we have to remove the entries from the queue's */
191 wrk = start_list;
192 while (wrk)
194 Event_Queue *tmp = (Event_Queue *)wrk->listhead;
196 while (tmp->forward != wrk)
197 tmp = tmp->forward;
198 tmp->forward = wrk->forward;
199 wrk = wrk->chain;
203 wrk = start_list;
204 while (wrk)
206 Event_Queue *tmp;
208 if (wrk->is_continued && ! already_done)
210 already_done = 1;
211 retval = wrk->listhead;
212 if (insloc && !timed_out)
214 insloc->ptype = wrk->who_continued.ptype;
215 insloc->pcopy = wrk->who_continued.pcopy;
218 tmp = wrk->chain;
219 FREE (wrk);
220 wrk = tmp;
222 if (!timed_out && ev_got)
223 *ev_got = (void *)retval;
224 return timed_out;
227 /* force function print_event to be linked */
228 extern void __print_event ();
229 static EntryPoint pev = __print_event;