1 /* GNU CHILL compiler regression test file
2 Copyright (C) 1992, 1993 Free Software Foundation, Inc.
4 This file is part of GNU CC.
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* As a special exception, if you link this library with other files,
21 some of which are compiled with GCC, to produce an executable,
22 this library does not by itself cause the resulting executable
23 to be covered by the GNU General Public License.
24 This exception does not however invalidate any other reasons why
25 the executable file might be covered by the GNU General Public License. */
36 /* some allocation/reallocation functions */
42 void *tmp = malloc (size);
46 fprintf (stderr, "Out of heap space.\n");
57 void *tmp = realloc (ptr, size);
61 fprintf (stderr, "Out of heap space.\n");
67 /* the necessary data */
68 #define MAX_NUMBER 100
69 typedef char UsedValues[MAX_NUMBER];
71 #define MAX_COPIES 100
73 #define MAX_PER_ITEM 20
74 typedef struct TASKINGSTRUCTLIST
76 struct TASKINGSTRUCTLIST *forward;
78 TaskingStruct *data[MAX_PER_ITEM];
79 char copies[MAX_COPIES];
83 static TaskingStructList *task_array[LAST_AND_UNUSED];
84 static UsedValues used_values[LAST_AND_UNUSED];
87 get_next_free_number (vals)
91 for (i = 1; i < MAX_NUMBER; i++)
99 fprintf (stderr, "There are no more free numbers.\n");
103 /* function search for the next available copy number */
105 get_next_copy_number (p)
106 TaskingStructList *p;
110 for (i = 0; i < MAX_COPIES; i++)
118 fprintf (stderr, "No more copies available for \"%s\".\n",
123 /* function registers a tasking entry from a module and assign
124 a value to the type */
127 __register_tasking (t)
130 TaskingStructList *p;
132 /* check first if a value was provided and if it is in range */
133 if (t->value_defined && *t->value >= MAX_NUMBER)
135 fprintf (stderr, "Value %d out of range.\n", *t->value);
139 /* look for item defined */
140 p = task_array[t->type];
143 if (!strcmp (p->data[0]->name, t->name))
151 TaskingStructList *wrk = (TaskingStructList *)&task_array[t->type];
153 /* this is a new one -- allocate space */
154 p = xmalloc (sizeof (TaskingStructList));
155 memset (p->copies, 0, sizeof (p->copies));
167 if (p->num >= MAX_PER_ITEM)
169 fprintf (stderr, "Too many registrations of \"%s\".\n", t->name);
172 p->data[p->num++] = t;
176 /* define all the entries for the runtime system. They will be
177 needed by chillrt0.o */
179 typedef char *(*fetch_names) ();
180 typedef int (*fetch_numbers) ();
182 static char tmp_for_fetch_name[100];
185 __fetch_name (number)
188 TaskingStructList *p = task_array[Process];
192 if (*(p->data[0]->value) == number)
193 return (p->data[0]->name);
196 sprintf (tmp_for_fetch_name, "%d", number);
197 return (tmp_for_fetch_name);
199 fetch_names __RTS_FETCH_NAMES__ = __fetch_name;
202 __fetch_number (name)
205 TaskingStructList *p = task_array[Process];
209 if (!strcmp (p->data[0]->name, name))
210 return (*(p->data[0]->value));
215 fetch_numbers __RTS_FETCH_NUMBERS__ = __fetch_number;
218 /* here we go to check all registered items */
223 TaskingStructList *p;
225 for (i = Process; i <= Event; i++)
230 TaskingStruct *t = 0;
234 for (j = 0; j < p->num; j++)
236 if (p->data[j]->value_defined)
240 if (*(t->value) != *(p->data[j]->value))
242 fprintf (stderr, "Different values (%d & %d) for \"%s\".",
243 *(t->value), *(p->data[j]->value), t->name);
257 if (used_values[t->type][val])
259 fprintf (stderr, "Value %d for \"%s\" is already used.\n",
263 used_values[t->type][val] = 1;
267 /* we have to create a new value */
268 val = get_next_free_number (used_values[p->data[0]->type]);
271 for (j = 0; j < p->num; j++)
273 p->data[j]->value_defined = 1;
274 *(p->data[j]->value) = val;
281 EntryPoint __RTS_INIT__ = __rts_init;
283 /* define the start process queue */
284 typedef struct STARTENTRY
286 struct STARTENTRY *forward;
293 static StartEntry *start_queue = 0;
294 static StartEntry *current_process = 0;
296 /* the jump buffer for the main loop */
297 static jmp_buf jump_buffer;
298 static int jump_buffer_initialized = 0;
300 /* look for entries in start_queue and start the process */
308 if (setjmp (jump_buffer) == 0)
310 jump_buffer_initialized = 1;
315 start_queue = s->forward;
317 /* call the process */
318 (*s->entry) (s->data);
321 /* when queue empty we have finished */
327 if (current_process->data)
328 free (current_process->data);
329 free (current_process);
334 EntryPoint __RTS_MAIN_LOOP__ = __rts_main_loop;
338 __start_process (ptype, pcopy, arg_size, args, ins)
345 TaskingStructList *p = task_array[Process];
348 short this_copy = pcopy;
351 /* search for the process */
354 if (*(p->data[0]->value) == ptype)
360 fprintf (stderr, "Cannot find a process with type %d.\n", ptype);
364 /* search for the entry point */
365 for (i = 0; i < p->num; i++)
367 if (p->data[i]->entry)
369 pc = p->data[i]->entry;
375 fprintf (stderr, "Process \"%s\" doesn't have an entry point.\n",
381 if (pcopy >= MAX_COPIES)
383 fprintf (stderr, "Copy number (%d) out of range.\n", pcopy);
388 /* search for a copy number */
389 this_copy = get_next_copy_number (p);
393 if (p->copies[pcopy])
395 /* FIXME: should be exception 'startfail' */
396 fprintf (stderr, "Copy number %d already in use for \"%s\".\n",
397 pcopy, p->data[0]->name);
400 p->copies[this_copy = pcopy] = 1;
403 /* ready to build start_queue entry */
404 s = xmalloc (sizeof (StartEntry));
406 s->whoami.pcopy = this_copy;
407 s->whoami.ptype = ptype;
409 s->datalen = arg_size;
412 s->data = xmalloc (arg_size);
413 memcpy (s->data, args, arg_size);
418 /* queue that stuff in */
419 wrk = (StartEntry *)&start_queue;
424 /* if we have a pointer to ins -- set it */
428 ins->pcopy = this_copy;
435 if (!jump_buffer_initialized)
437 fprintf (stderr, "STOP called before START.\n");
440 longjmp (jump_buffer, 1);
444 /* function returns INSTANCE of current process */
450 whoami = current_process->whoami;
466 typedef struct SIGNALQUEUE
468 struct SIGNALQUEUE *forward;
476 /* define the signal queue */
477 static SignalQueue *msg_queue = 0;
481 __send_signal (s, to, prio, with_len, with)
488 SignalQueue *wrk = (SignalQueue *)&msg_queue;
490 TaskingStructList *t = task_array[Process];
492 /* search for process is defined and running */
495 if (*(t->data[0]->value) == to.ptype)
499 if (!t || !t->copies[to.pcopy])
501 fprintf (stderr, "Can't find instance [%d,%d].\n",
506 /* go to the end of the msg_queue */
510 p = xmalloc (sizeof (SignalQueue));
512 if (p->data_len = s->data_len)
514 p->data = xmalloc (s->data_len);
515 memcpy (p->data, s->data, s->data_len);
520 p->from = __whoami ();
526 start_signal_timeout (i, s, j)
531 __send_signal (s, __whoami (), 0, 0, 0);
535 /* receive a signal */
537 __wait_signal_timed (sig_got, nsigs, sigptr, datap,
538 datalen, ins, else_branche,
539 to, filename, lineno)
551 INSTANCE me = __whoami ();
552 SignalQueue *wrk, *p = msg_queue;
556 /* search for a signal to `me' */
557 wrk = (SignalQueue *)&msg_queue;
561 if (p->to.ptype == me.ptype
562 && p->to.pcopy == me.pcopy)
570 fprintf (stderr, "No signal for [%d,%d].\n",
575 /* queue the message out */
576 wrk->forward = p->forward;
578 /* now look for signal in list */
579 for (i = 0; i < nsigs; i++)
580 if (*(sigptr[i]) == p->sc)
583 if (i >= nsigs && ! else_branche)
584 /* signal not in list and no ELSE in code */
585 __cause_exception ("signalfail", __FILE__, __LINE__);
589 /* signal not in list */
600 /* we have found a signal in the list */
603 if (datalen >= p->data_len
605 memcpy (datap, p->data, p->data_len);
607 __cause_exception ("spacefail", __FILE__, __LINE__);
620 /* wait a certain amount of seconds */
622 __sleep_till (abstime, reltime, fname, lineno)
632 /* set up an alarm */
633 static int timeout_flag = 0;
635 static void alarm_handler ()
641 __define_timeout (howlong, filename, lineno)
642 unsigned long howlong; /* comes in millisecs */
646 unsigned int prev_alarm_value;
648 signal (SIGALRM, alarm_handler);
649 prev_alarm_value = alarm ((unsigned int)(howlong / 1000));
650 return &timeout_flag;
653 /* wait till timeout expires */
655 __wait_timeout (toid, filename, lineno)