OSDN Git Service

* gjavah.c (print_class_decls): Fix thinko in arglist
[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, 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 #include "rtltypes.h"
22 #include "rts.h"
23
24 extern void __cause_ex1 (char *ex, char *file, int lineno);
25
26 EXCEPTION (delayfail);
27 #define CAUSE_DELAYFAIL     __cause_ex1 ("delayfail", filename, lineno)
28
29 EXCEPTION (notyetimplemented);
30 #define CAUSE_NOTIMPLEMENTED   __cause_ex1 ("notyetimplemeyed", filename, lineno)
31
32 /*
33  * function __delay_event
34  *
35  * parameters:
36  *     ev_got      pointer to location where to write the event got.
37  *     nevents     number of events in list
38  *     evptrs      array of event descriptors
39  *     priority    specified priority
40  *     insloc      pointer to resulting instance location
41  *     to          timeout value
42  *     filename    filename of caller
43  *     lineno      linenumber of caller
44  *
45  * returns:
46  *     int         0 .. success
47  *                 1 .. timed out
48  *
49  * exceptions:
50  *     delayfail
51  *
52  * abstract:
53  *     implement the CHILL DELAY and DELAY CASE actions.
54  *
55  */
56
57 int
58 __delay_event (ev_got, nevents, evptrs, priority, to, insloc, filename, lineno)
59      void         **ev_got;
60      int            nevents;
61      Event_Descr   *evptrs;
62      int            priority;
63      void          *to;
64      INSTANCE      *insloc;
65      char          *filename;
66      int            lineno;
67 {
68   int             i, already_done = 0;
69   Event_Queue    *start_list = 0;
70   Event_Queue   **retval = 0;
71   Event_Queue    *wrk;
72   int             timed_out = 0;
73   
74   /* check if all specified event queues have enough space left
75      to perform the delay */
76   for (i = 0; i < nevents; i++)
77     {
78       Event_Queue  *e;
79       unsigned long cnt = 0;
80       int j, have_done = 0;
81
82       if (evptrs[i].maxqueuelength == 0)
83         CAUSE_DELAYFAIL;
84       else if (evptrs[i].maxqueuelength == (unsigned long)-1L)
85         /* infinite length */
86         continue;
87
88       /* check if we already have processed this one, that means, this
89          event is mentioned more then once */
90       for (j = 0; j < i; j++)
91         {
92           if (evptrs[i].ev == evptrs[j].ev)
93             {
94               have_done = 1;
95               break;
96             }
97         }
98       if (have_done)
99         continue;
100       
101       memcpy (&e, evptrs[i].ev, sizeof (Event_Queue *));
102       while (e)
103         {
104           cnt++;
105           e = e->forward;
106         }
107       if (cnt >= evptrs[i].maxqueuelength)
108         CAUSE_DELAYFAIL;
109     }
110
111   for (i = 0; i < nevents; i++)
112     {
113       /* queue that stuff on each event */
114       Event_Queue      *wrk;
115       Event_Queue      *ev;
116       Event_Queue      *prev_queue_entry = 0;
117       Event_Queue      *prev_list_entry;
118       int               j, have_done = 0;
119       
120       /* check for this event already processed */
121       for (j = 0; j < i; j++)
122         {
123           if (evptrs[i].ev == evptrs[j].ev)
124             {
125               have_done = 1;
126               break;
127             }
128         }
129       if (have_done)
130         continue;
131
132       memcpy (&ev, &evptrs[i].ev, sizeof (Event_Queue *));
133       MALLOC (wrk, sizeof (Event_Queue));
134       memset (wrk, 0, sizeof (Event_Queue));
135
136       wrk->priority = priority;
137       wrk->this = THIS;
138       wrk->listhead = evptrs[i].ev;
139
140       /* search for the place to queue this entry in */
141       while (ev->forward != 0 && ev->priority >= priority)
142         {
143           prev_queue_entry = ev;
144           ev = ev->forward;
145         }
146
147       /* ready to put entry into queue */
148       if (ev->forward == 0 || prev_queue_entry == 0)
149         {
150           /* beginning or end of the list */
151           wrk->forward = ev->forward;
152           ev->forward = wrk;
153         }
154       else
155         {
156           /* this is somewhere in the middle */
157           wrk->forward = prev_queue_entry->forward;
158           prev_queue_entry->forward = wrk;
159         }
160
161       /* queue it into list */
162       wrk->startlist = start_list;
163       if (! start_list)
164         {
165           /* we are the first in the list */
166           start_list = wrk;
167           prev_list_entry = wrk;
168           wrk->startlist = start_list;
169         }
170       else
171         {
172           prev_list_entry->chain = wrk;
173           prev_list_entry = wrk;
174         }
175     }
176
177   /* tell runtime system to delay that process */
178   timed_out = __delay_this (wait_event_delay, to, filename, lineno);
179   if (timed_out)
180     {
181       /* we have to remove the entries from the queue's */
182       wrk = start_list;
183       while (wrk)
184         {
185           Event_Queue *tmp = (Event_Queue *)wrk->listhead;
186           
187           while (tmp->forward != wrk)
188             tmp = tmp->forward;
189           tmp->forward = wrk->forward;
190           wrk = wrk->chain;
191         }
192     }
193   
194   wrk = start_list;
195   while (wrk)
196     {
197       Event_Queue  *tmp;
198
199       if (wrk->is_continued && ! already_done)
200         {
201           already_done = 1;
202           retval = wrk->listhead;
203           if (insloc && !timed_out)
204             {
205               insloc->ptype = wrk->who_continued.ptype;
206               insloc->pcopy = wrk->who_continued.pcopy;
207             }
208         }
209       tmp = wrk->chain;
210       FREE (wrk);
211       wrk = tmp;
212     }
213   if (!timed_out && ev_got)
214     *ev_got = (void *)retval;
215   return timed_out;
216 }
217
218 /* force function print_event to be linked */
219 extern void __print_event ();
220 static EntryPoint pev = __print_event;