* optabs.c (init_traps): Register trap_rtx as a GC root.
[official-gcc.git] / libchill / delaycase.c
blobf66f10c8c40925537dd2901503a44e76a1c8d7e7
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 "rtltypes.h"
30 #include "rts.h"
32 extern void __cause_ex1 (char *ex, char *file, int lineno);
34 EXCEPTION (delayfail);
35 #define CAUSE_DELAYFAIL __cause_ex1 ("delayfail", filename, lineno)
37 EXCEPTION (notyetimplemented);
38 #define CAUSE_NOTIMPLEMENTED __cause_ex1 ("notyetimplemeyed", filename, lineno)
41 * function __delay_event
43 * parameters:
44 * ev_got pointer to location where to write the event got.
45 * nevents number of events in list
46 * evptrs array of event descriptors
47 * priority specified priority
48 * insloc pointer to resulting instance location
49 * to timeout value
50 * filename filename of caller
51 * lineno linenumber of caller
53 * returns:
54 * int 0 .. success
55 * 1 .. timed out
57 * exceptions:
58 * delayfail
60 * abstract:
61 * implement the CHILL DELAY and DELAY CASE actions.
65 int
66 __delay_event (ev_got, nevents, evptrs, priority, to, insloc, filename, lineno)
67 void **ev_got;
68 int nevents;
69 Event_Descr *evptrs;
70 int priority;
71 void *to;
72 INSTANCE *insloc;
73 char *filename;
74 int lineno;
76 int i, already_done = 0;
77 Event_Queue *start_list = 0;
78 Event_Queue **retval = 0;
79 Event_Queue *wrk;
80 int timed_out = 0;
82 /* check if all specified event queues have enough space left
83 to perform the delay */
84 for (i = 0; i < nevents; i++)
86 Event_Queue *e;
87 unsigned long cnt = 0;
88 int j, have_done = 0;
90 if (evptrs[i].maxqueuelength == 0)
91 CAUSE_DELAYFAIL;
92 else if (evptrs[i].maxqueuelength == (unsigned long)-1L)
93 /* infinite length */
94 continue;
96 /* check if we already have processed this one, that means, this
97 event is mentioned more then once */
98 for (j = 0; j < i; j++)
100 if (evptrs[i].ev == evptrs[j].ev)
102 have_done = 1;
103 break;
106 if (have_done)
107 continue;
109 memcpy (&e, evptrs[i].ev, sizeof (Event_Queue *));
110 while (e)
112 cnt++;
113 e = e->forward;
115 if (cnt >= evptrs[i].maxqueuelength)
116 CAUSE_DELAYFAIL;
119 for (i = 0; i < nevents; i++)
121 /* queue that stuff on each event */
122 Event_Queue *wrk;
123 Event_Queue *ev;
124 Event_Queue *prev_queue_entry = 0;
125 Event_Queue *prev_list_entry;
126 int j, have_done = 0;
128 /* check for this event already processed */
129 for (j = 0; j < i; j++)
131 if (evptrs[i].ev == evptrs[j].ev)
133 have_done = 1;
134 break;
137 if (have_done)
138 continue;
140 memcpy (&ev, &evptrs[i].ev, sizeof (Event_Queue *));
141 MALLOC (wrk, sizeof (Event_Queue));
142 memset (wrk, 0, sizeof (Event_Queue));
144 wrk->priority = priority;
145 wrk->this = THIS;
146 wrk->listhead = evptrs[i].ev;
148 /* search for the place to queue this entry in */
149 while (ev->forward != 0 && ev->priority >= priority)
151 prev_queue_entry = ev;
152 ev = ev->forward;
155 /* ready to put entry into queue */
156 if (ev->forward == 0 || prev_queue_entry == 0)
158 /* beginning or end of the list */
159 wrk->forward = ev->forward;
160 ev->forward = wrk;
162 else
164 /* this is somewhere in the middle */
165 wrk->forward = prev_queue_entry->forward;
166 prev_queue_entry->forward = wrk;
169 /* queue it into list */
170 wrk->startlist = start_list;
171 if (! start_list)
173 /* we are the first in the list */
174 start_list = wrk;
175 prev_list_entry = wrk;
176 wrk->startlist = start_list;
178 else
180 prev_list_entry->chain = wrk;
181 prev_list_entry = wrk;
185 /* tell runtime system to delay that process */
186 timed_out = __delay_this (wait_event_delay, to, filename, lineno);
187 if (timed_out)
189 /* we have to remove the entries from the queue's */
190 wrk = start_list;
191 while (wrk)
193 Event_Queue *tmp = (Event_Queue *)wrk->listhead;
195 while (tmp->forward != wrk)
196 tmp = tmp->forward;
197 tmp->forward = wrk->forward;
198 wrk = wrk->chain;
202 wrk = start_list;
203 while (wrk)
205 Event_Queue *tmp;
207 if (wrk->is_continued && ! already_done)
209 already_done = 1;
210 retval = wrk->listhead;
211 if (insloc && !timed_out)
213 insloc->ptype = wrk->who_continued.ptype;
214 insloc->pcopy = wrk->who_continued.pcopy;
217 tmp = wrk->chain;
218 FREE (wrk);
219 wrk = tmp;
221 if (!timed_out && ev_got)
222 *ev_got = (void *)retval;
223 return timed_out;
226 /* force function print_event to be linked */
227 extern void __print_event ();
228 static EntryPoint pev = __print_event;