OSDN Git Service

* parse.y (check_static_final_variable_assignment_flag): Fix spelling.
[pf3gnuchains/gcc-fork.git] / libchill / delaycase.c
1 /* Implement tasking-related runtime actions for CHILL.
2    Copyright (C) 1992,1993 Free Software Foundation, Inc.
3    Author: Wilfried Moser
4
5 This file is part of GNU CC.
6
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.
11
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.
16
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.  */
21
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.  */
28
29 #include <string.h>
30 #include "rtltypes.h"
31 #include "rts.h"
32
33 extern void __cause_ex1 (char *ex, char *file, int lineno);
34
35 EXCEPTION (delayfail);
36 #define CAUSE_DELAYFAIL     __cause_ex1 ("delayfail", filename, lineno)
37
38 EXCEPTION (notyetimplemented);
39 #define CAUSE_NOTIMPLEMENTED   __cause_ex1 ("notyetimplemeyed", filename, lineno)
40
41 /*
42  * function __delay_event
43  *
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
53  *
54  * returns:
55  *     int         0 .. success
56  *                 1 .. timed out
57  *
58  * exceptions:
59  *     delayfail
60  *
61  * abstract:
62  *     implement the CHILL DELAY and DELAY CASE actions.
63  *
64  */
65
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;
76 {
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;
82   
83   /* check if all specified event queues have enough space left
84      to perform the delay */
85   for (i = 0; i < nevents; i++)
86     {
87       Event_Queue  *e;
88       unsigned long cnt = 0;
89       int j, have_done = 0;
90
91       if (evptrs[i].maxqueuelength == 0)
92         CAUSE_DELAYFAIL;
93       else if (evptrs[i].maxqueuelength == (unsigned long)-1L)
94         /* infinite length */
95         continue;
96
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++)
100         {
101           if (evptrs[i].ev == evptrs[j].ev)
102             {
103               have_done = 1;
104               break;
105             }
106         }
107       if (have_done)
108         continue;
109       
110       memcpy (&e, evptrs[i].ev, sizeof (Event_Queue *));
111       while (e)
112         {
113           cnt++;
114           e = e->forward;
115         }
116       if (cnt >= evptrs[i].maxqueuelength)
117         CAUSE_DELAYFAIL;
118     }
119
120   for (i = 0; i < nevents; i++)
121     {
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;
128       
129       /* check for this event already processed */
130       for (j = 0; j < i; j++)
131         {
132           if (evptrs[i].ev == evptrs[j].ev)
133             {
134               have_done = 1;
135               break;
136             }
137         }
138       if (have_done)
139         continue;
140
141       memcpy (&ev, &evptrs[i].ev, sizeof (Event_Queue *));
142       MALLOC (wrk, sizeof (Event_Queue));
143       memset (wrk, 0, sizeof (Event_Queue));
144
145       wrk->priority = priority;
146       wrk->this = THIS;
147       wrk->listhead = evptrs[i].ev;
148
149       /* search for the place to queue this entry in */
150       while (ev->forward != 0 && ev->priority >= priority)
151         {
152           prev_queue_entry = ev;
153           ev = ev->forward;
154         }
155
156       /* ready to put entry into queue */
157       if (ev->forward == 0 || prev_queue_entry == 0)
158         {
159           /* beginning or end of the list */
160           wrk->forward = ev->forward;
161           ev->forward = wrk;
162         }
163       else
164         {
165           /* this is somewhere in the middle */
166           wrk->forward = prev_queue_entry->forward;
167           prev_queue_entry->forward = wrk;
168         }
169
170       /* queue it into list */
171       wrk->startlist = start_list;
172       if (! start_list)
173         {
174           /* we are the first in the list */
175           start_list = wrk;
176           prev_list_entry = wrk;
177           wrk->startlist = start_list;
178         }
179       else
180         {
181           prev_list_entry->chain = wrk;
182           prev_list_entry = wrk;
183         }
184     }
185
186   /* tell runtime system to delay that process */
187   timed_out = __delay_this (wait_event_delay, to, filename, lineno);
188   if (timed_out)
189     {
190       /* we have to remove the entries from the queue's */
191       wrk = start_list;
192       while (wrk)
193         {
194           Event_Queue *tmp = (Event_Queue *)wrk->listhead;
195           
196           while (tmp->forward != wrk)
197             tmp = tmp->forward;
198           tmp->forward = wrk->forward;
199           wrk = wrk->chain;
200         }
201     }
202   
203   wrk = start_list;
204   while (wrk)
205     {
206       Event_Queue  *tmp;
207
208       if (wrk->is_continued && ! already_done)
209         {
210           already_done = 1;
211           retval = wrk->listhead;
212           if (insloc && !timed_out)
213             {
214               insloc->ptype = wrk->who_continued.ptype;
215               insloc->pcopy = wrk->who_continued.pcopy;
216             }
217         }
218       tmp = wrk->chain;
219       FREE (wrk);
220       wrk = tmp;
221     }
222   if (!timed_out && ev_got)
223     *ev_got = (void *)retval;
224   return timed_out;
225 }
226
227 /* force function print_event to be linked */
228 extern void __print_event ();
229 static EntryPoint pev = __print_event;