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, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, 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. */
37 /* some allocation/reallocation functions */
43 void *tmp
= malloc (size
);
47 fprintf (stderr
, "Out of heap space.\n");
58 void *tmp
= realloc (ptr
, size
);
62 fprintf (stderr
, "Out of heap space.\n");
68 /* the necessary data */
69 #define MAX_NUMBER 100
70 typedef char UsedValues
[MAX_NUMBER
];
72 #define MAX_COPIES 100
74 #define MAX_PER_ITEM 20
75 typedef struct TASKINGSTRUCTLIST
77 struct TASKINGSTRUCTLIST
*forward
;
79 TaskingStruct
*data
[MAX_PER_ITEM
];
80 char copies
[MAX_COPIES
];
84 static TaskingStructList
*task_array
[LAST_AND_UNUSED
];
85 static UsedValues used_values
[LAST_AND_UNUSED
];
88 get_next_free_number (vals
)
92 for (i
= 1; i
< MAX_NUMBER
; i
++)
100 fprintf (stderr
, "There are no more free numbers.\n");
104 /* function search for the next available copy number */
106 get_next_copy_number (p
)
107 TaskingStructList
*p
;
111 for (i
= 0; i
< MAX_COPIES
; i
++)
119 fprintf (stderr
, "No more copies available for \"%s\".\n",
124 /* function registers a tasking entry from a module and assign
125 a value to the type */
128 __register_tasking (t
)
131 TaskingStructList
*p
;
133 /* check first if a value was provided and if it is in range */
134 if (t
->value_defined
&& *t
->value
>= MAX_NUMBER
)
136 fprintf (stderr
, "Value %d out of range.\n", *t
->value
);
140 /* look for item defined */
141 p
= task_array
[t
->type
];
144 if (!strcmp (p
->data
[0]->name
, t
->name
))
152 TaskingStructList
*wrk
= (TaskingStructList
*)&task_array
[t
->type
];
154 /* this is a new one -- allocate space */
155 p
= xmalloc (sizeof (TaskingStructList
));
156 memset (p
->copies
, 0, sizeof (p
->copies
));
168 if (p
->num
>= MAX_PER_ITEM
)
170 fprintf (stderr
, "Too many registrations of \"%s\".\n", t
->name
);
173 p
->data
[p
->num
++] = t
;
177 /* define all the entries for the runtime system. They will be
178 needed by chillrt0.o */
180 typedef char *(*fetch_names
) ();
181 typedef int (*fetch_numbers
) ();
183 static char tmp_for_fetch_name
[100];
186 __fetch_name (number
)
189 TaskingStructList
*p
= task_array
[Process
];
193 if (*(p
->data
[0]->value
) == number
)
194 return (p
->data
[0]->name
);
197 sprintf (tmp_for_fetch_name
, "%d", number
);
198 return (tmp_for_fetch_name
);
200 fetch_names __RTS_FETCH_NAMES__
= __fetch_name
;
203 __fetch_number (name
)
206 TaskingStructList
*p
= task_array
[Process
];
210 if (!strcmp (p
->data
[0]->name
, name
))
211 return (*(p
->data
[0]->value
));
216 fetch_numbers __RTS_FETCH_NUMBERS__
= __fetch_number
;
219 /* here we go to check all registered items */
224 TaskingStructList
*p
;
226 for (i
= Process
; i
<= Event
; i
++)
231 TaskingStruct
*t
= 0;
235 for (j
= 0; j
< p
->num
; j
++)
237 if (p
->data
[j
]->value_defined
)
241 if (*(t
->value
) != *(p
->data
[j
]->value
))
243 fprintf (stderr
, "Different values (%d & %d) for \"%s\".",
244 *(t
->value
), *(p
->data
[j
]->value
), t
->name
);
258 if (used_values
[t
->type
][val
])
260 fprintf (stderr
, "Value %d for \"%s\" is already used.\n",
264 used_values
[t
->type
][val
] = 1;
268 /* we have to create a new value */
269 val
= get_next_free_number (used_values
[p
->data
[0]->type
]);
272 for (j
= 0; j
< p
->num
; j
++)
274 p
->data
[j
]->value_defined
= 1;
275 *(p
->data
[j
]->value
) = val
;
282 EntryPoint __RTS_INIT__
= __rts_init
;
284 /* define the start process queue */
285 typedef struct STARTENTRY
287 struct STARTENTRY
*forward
;
294 static StartEntry
*start_queue
= 0;
295 static StartEntry
*current_process
= 0;
297 /* the jump buffer for the main loop */
298 static jmp_buf jump_buffer
;
299 static int jump_buffer_initialized
= 0;
301 /* look for entries in start_queue and start the process */
309 if (setjmp (jump_buffer
) == 0)
311 jump_buffer_initialized
= 1;
316 start_queue
= s
->forward
;
318 /* call the process */
319 (*s
->entry
) (s
->data
);
322 /* when queue empty we have finished */
328 if (current_process
->data
)
329 free (current_process
->data
);
330 free (current_process
);
335 EntryPoint __RTS_MAIN_LOOP__
= __rts_main_loop
;
339 __start_process (ptype
, pcopy
, arg_size
, args
, ins
)
346 TaskingStructList
*p
= task_array
[Process
];
349 short this_copy
= pcopy
;
352 /* search for the process */
355 if (*(p
->data
[0]->value
) == ptype
)
361 fprintf (stderr
, "Cannot find a process with type %d.\n", ptype
);
365 /* search for the entry point */
366 for (i
= 0; i
< p
->num
; i
++)
368 if (p
->data
[i
]->entry
)
370 pc
= p
->data
[i
]->entry
;
376 fprintf (stderr
, "Process \"%s\" doesn't have an entry point.\n",
382 if (pcopy
>= MAX_COPIES
)
384 fprintf (stderr
, "Copy number (%d) out of range.\n", pcopy
);
389 /* search for a copy number */
390 this_copy
= get_next_copy_number (p
);
394 if (p
->copies
[pcopy
])
396 /* FIXME: should be exception 'startfail' */
397 fprintf (stderr
, "Copy number %d already in use for \"%s\".\n",
398 pcopy
, p
->data
[0]->name
);
401 p
->copies
[this_copy
= pcopy
] = 1;
404 /* ready to build start_queue entry */
405 s
= xmalloc (sizeof (StartEntry
));
407 s
->whoami
.pcopy
= this_copy
;
408 s
->whoami
.ptype
= ptype
;
410 s
->datalen
= arg_size
;
413 s
->data
= xmalloc (arg_size
);
414 memcpy (s
->data
, args
, arg_size
);
419 /* queue that stuff in */
420 wrk
= (StartEntry
*)&start_queue
;
425 /* if we have a pointer to ins -- set it */
429 ins
->pcopy
= this_copy
;
436 if (!jump_buffer_initialized
)
438 fprintf (stderr
, "STOP called before START.\n");
441 longjmp (jump_buffer
, 1);
445 /* function returns INSTANCE of current process */
451 whoami
= current_process
->whoami
;
467 typedef struct SIGNALQUEUE
469 struct SIGNALQUEUE
*forward
;
477 /* define the signal queue */
478 static SignalQueue
*msg_queue
= 0;
482 __send_signal (s
, to
, prio
, with_len
, with
)
489 SignalQueue
*wrk
= (SignalQueue
*)&msg_queue
;
491 TaskingStructList
*t
= task_array
[Process
];
493 /* search for process is defined and running */
496 if (*(t
->data
[0]->value
) == to
.ptype
)
500 if (!t
|| !t
->copies
[to
.pcopy
])
502 fprintf (stderr
, "Can't find instance [%d,%d].\n",
507 /* go to the end of the msg_queue */
511 p
= xmalloc (sizeof (SignalQueue
));
513 if (p
->data_len
= s
->data_len
)
515 p
->data
= xmalloc (s
->data_len
);
516 memcpy (p
->data
, s
->data
, s
->data_len
);
521 p
->from
= __whoami ();
527 start_signal_timeout (i
, s
, j
)
532 __send_signal (s
, __whoami (), 0, 0, 0);
536 /* receive a signal */
538 __wait_signal_timed (sig_got
, nsigs
, sigptr
, datap
,
539 datalen
, ins
, else_branche
,
540 to
, filename
, lineno
)
552 INSTANCE me
= __whoami ();
553 SignalQueue
*wrk
, *p
= msg_queue
;
557 /* search for a signal to `me' */
558 wrk
= (SignalQueue
*)&msg_queue
;
562 if (p
->to
.ptype
== me
.ptype
563 && p
->to
.pcopy
== me
.pcopy
)
571 fprintf (stderr
, "No signal for [%d,%d].\n",
576 /* queue the message out */
577 wrk
->forward
= p
->forward
;
579 /* now look for signal in list */
580 for (i
= 0; i
< nsigs
; i
++)
581 if (*(sigptr
[i
]) == p
->sc
)
584 if (i
>= nsigs
&& ! else_branche
)
585 /* signal not in list and no ELSE in code */
586 __cause_exception ("signalfail", __FILE__
, __LINE__
);
590 /* signal not in list */
601 /* we have found a signal in the list */
604 if (datalen
>= p
->data_len
606 memcpy (datap
, p
->data
, p
->data_len
);
608 __cause_exception ("spacefail", __FILE__
, __LINE__
);
621 /* wait a certain amount of seconds */
623 __sleep_till (abstime
, reltime
, fname
, lineno
)
633 /* set up an alarm */
634 static int timeout_flag
= 0;
636 static void alarm_handler ()
642 __define_timeout (howlong
, filename
, lineno
)
643 unsigned long howlong
; /* comes in millisecs */
647 unsigned int prev_alarm_value
;
649 signal (SIGALRM
, alarm_handler
);
650 prev_alarm_value
= alarm ((unsigned int)(howlong
/ 1000));
651 return &timeout_flag
;
654 /* wait till timeout expires */
656 __wait_timeout (toid
, filename
, lineno
)