1 /* Implement tasking-related runtime actions for CHILL.
2 Copyright (C) 1992,1993 Free Software Foundation, Inc.
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)
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. */
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
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
49 * filename filename of caller
50 * lineno linenumber of caller
60 * implement the CHILL DELAY and DELAY CASE actions.
65 __delay_event (ev_got
, nevents
, evptrs
, priority
, to
, insloc
, filename
, lineno
)
75 int i
, already_done
= 0;
76 Event_Queue
*start_list
= 0;
77 Event_Queue
**retval
= 0;
81 /* check if all specified event queues have enough space left
82 to perform the delay */
83 for (i
= 0; i
< nevents
; i
++)
86 unsigned long cnt
= 0;
89 if (evptrs
[i
].maxqueuelength
== 0)
91 else if (evptrs
[i
].maxqueuelength
== (unsigned long)-1L)
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
)
108 memcpy (&e
, evptrs
[i
].ev
, sizeof (Event_Queue
*));
114 if (cnt
>= evptrs
[i
].maxqueuelength
)
118 for (i
= 0; i
< nevents
; i
++)
120 /* queue that stuff on each event */
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
)
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
;
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
;
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
;
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
;
172 /* we are the first in the list */
174 prev_list_entry
= wrk
;
175 wrk
->startlist
= start_list
;
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
);
188 /* we have to remove the entries from the queue's */
192 Event_Queue
*tmp
= (Event_Queue
*)wrk
->listhead
;
194 while (tmp
->forward
!= wrk
)
196 tmp
->forward
= wrk
->forward
;
206 if (wrk
->is_continued
&& ! already_done
)
209 retval
= wrk
->listhead
;
210 if (insloc
&& !timed_out
)
212 insloc
->ptype
= wrk
->who_continued
.ptype
;
213 insloc
->pcopy
= wrk
->who_continued
.pcopy
;
220 if (!timed_out
&& ev_got
)
221 *ev_got
= (void *)retval
;
225 /* force function print_event to be linked */
226 extern void __print_event ();
227 static EntryPoint pev
= __print_event
;