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, 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. */
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
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
50 * filename filename of caller
51 * lineno linenumber of caller
61 * implement the CHILL DELAY and DELAY CASE actions.
66 __delay_event (ev_got
, nevents
, evptrs
, priority
, to
, insloc
, filename
, lineno
)
76 int i
, already_done
= 0;
77 Event_Queue
*start_list
= 0;
78 Event_Queue
**retval
= 0;
82 /* check if all specified event queues have enough space left
83 to perform the delay */
84 for (i
= 0; i
< nevents
; i
++)
87 unsigned long cnt
= 0;
90 if (evptrs
[i
].maxqueuelength
== 0)
92 else if (evptrs
[i
].maxqueuelength
== (unsigned long)-1L)
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
)
109 memcpy (&e
, evptrs
[i
].ev
, sizeof (Event_Queue
*));
115 if (cnt
>= evptrs
[i
].maxqueuelength
)
119 for (i
= 0; i
< nevents
; i
++)
121 /* queue that stuff on each event */
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
)
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
;
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
;
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
;
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
;
173 /* we are the first in the list */
175 prev_list_entry
= wrk
;
176 wrk
->startlist
= start_list
;
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
);
189 /* we have to remove the entries from the queue's */
193 Event_Queue
*tmp
= (Event_Queue
*)wrk
->listhead
;
195 while (tmp
->forward
!= wrk
)
197 tmp
->forward
= wrk
->forward
;
207 if (wrk
->is_continued
&& ! already_done
)
210 retval
= wrk
->listhead
;
211 if (insloc
&& !timed_out
)
213 insloc
->ptype
= wrk
->who_continued
.ptype
;
214 insloc
->pcopy
= wrk
->who_continued
.pcopy
;
221 if (!timed_out
&& ev_got
)
222 *ev_got
= (void *)retval
;
226 /* force function print_event to be linked */
227 extern void __print_event ();
228 static EntryPoint pev
= __print_event
;