diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-09-05 01:11:54 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-09-05 01:11:54 +0000 |
commit | ffcbbbab99149ea7d8e800326458b70b54438076 (patch) | |
tree | e2a997b294961a00f5d259edefbef93b8501c089 /libchill/delaycase.c | |
parent | ff8e09bdcb33f98c7094eec337fb5e93da360a0d (diff) | |
download | gcc-ffcbbbab99149ea7d8e800326458b70b54438076.tar.gz |
* Chill runtime moved into toplevel libchill.
* Makefile.in Revamped due to move. Add multilib support.
* configure.in: Similarly. Use autoconf.
* powerset.h: Do not depend on BITS_PER_UNIT.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@22238 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libchill/delaycase.c')
-rw-r--r-- | libchill/delaycase.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/libchill/delaycase.c b/libchill/delaycase.c new file mode 100644 index 00000000000..22db5343d67 --- /dev/null +++ b/libchill/delaycase.c @@ -0,0 +1,220 @@ +/* Implement tasking-related runtime actions for CHILL. + Copyright (C) 1992,1993 Free Software Foundation, Inc. + Author: Wilfried Moser + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU CC is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include "rtltypes.h" +#include "rts.h" + +extern void __cause_ex1 (char *ex, char *file, int lineno); + +EXCEPTION (delayfail); +#define CAUSE_DELAYFAIL __cause_ex1 ("delayfail", filename, lineno) + +EXCEPTION (notyetimplemented); +#define CAUSE_NOTIMPLEMENTED __cause_ex1 ("notyetimplemeyed", filename, lineno) + +/* + * function __delay_event + * + * parameters: + * ev_got pointer to location where to write the event got. + * nevents number of events in list + * evptrs array of event descriptors + * priority specified priority + * insloc pointer to resulting instance location + * to timeout value + * filename filename of caller + * lineno linenumber of caller + * + * returns: + * int 0 .. success + * 1 .. timed out + * + * exceptions: + * delayfail + * + * abstract: + * implement the CHILL DELAY and DELAY CASE actions. + * + */ + +int +__delay_event (ev_got, nevents, evptrs, priority, to, insloc, filename, lineno) + void **ev_got; + int nevents; + Event_Descr *evptrs; + int priority; + void *to; + INSTANCE *insloc; + char *filename; + int lineno; +{ + int i, already_done = 0; + Event_Queue *start_list = 0; + Event_Queue **retval = 0; + Event_Queue *wrk; + int timed_out = 0; + + /* check if all specified event queues have enough space left + to perform the delay */ + for (i = 0; i < nevents; i++) + { + Event_Queue *e; + unsigned long cnt = 0; + int j, have_done = 0; + + if (evptrs[i].maxqueuelength == 0) + CAUSE_DELAYFAIL; + else if (evptrs[i].maxqueuelength == (unsigned long)-1L) + /* infinite length */ + continue; + + /* check if we already have processed this one, that means, this + event is mentioned more then once */ + for (j = 0; j < i; j++) + { + if (evptrs[i].ev == evptrs[j].ev) + { + have_done = 1; + break; + } + } + if (have_done) + continue; + + memcpy (&e, evptrs[i].ev, sizeof (Event_Queue *)); + while (e) + { + cnt++; + e = e->forward; + } + if (cnt >= evptrs[i].maxqueuelength) + CAUSE_DELAYFAIL; + } + + for (i = 0; i < nevents; i++) + { + /* queue that stuff on each event */ + Event_Queue *wrk; + Event_Queue *ev; + Event_Queue *prev_queue_entry = 0; + Event_Queue *prev_list_entry; + int j, have_done = 0; + + /* check for this event already processed */ + for (j = 0; j < i; j++) + { + if (evptrs[i].ev == evptrs[j].ev) + { + have_done = 1; + break; + } + } + if (have_done) + continue; + + memcpy (&ev, &evptrs[i].ev, sizeof (Event_Queue *)); + MALLOC (wrk, sizeof (Event_Queue)); + memset (wrk, 0, sizeof (Event_Queue)); + + wrk->priority = priority; + wrk->this = THIS; + wrk->listhead = evptrs[i].ev; + + /* search for the place to queue this entry in */ + while (ev->forward != 0 && ev->priority >= priority) + { + prev_queue_entry = ev; + ev = ev->forward; + } + + /* ready to put entry into queue */ + if (ev->forward == 0 || prev_queue_entry == 0) + { + /* beginning or end of the list */ + wrk->forward = ev->forward; + ev->forward = wrk; + } + else + { + /* this is somewhere in the middle */ + wrk->forward = prev_queue_entry->forward; + prev_queue_entry->forward = wrk; + } + + /* queue it into list */ + wrk->startlist = start_list; + if (! start_list) + { + /* we are the first in the list */ + start_list = wrk; + prev_list_entry = wrk; + wrk->startlist = start_list; + } + else + { + prev_list_entry->chain = wrk; + prev_list_entry = wrk; + } + } + + /* tell runtime system to delay that process */ + timed_out = __delay_this (wait_event_delay, to, filename, lineno); + if (timed_out) + { + /* we have to remove the entries from the queue's */ + wrk = start_list; + while (wrk) + { + Event_Queue *tmp = (Event_Queue *)wrk->listhead; + + while (tmp->forward != wrk) + tmp = tmp->forward; + tmp->forward = wrk->forward; + wrk = wrk->chain; + } + } + + wrk = start_list; + while (wrk) + { + Event_Queue *tmp; + + if (wrk->is_continued && ! already_done) + { + already_done = 1; + retval = wrk->listhead; + if (insloc && !timed_out) + { + insloc->ptype = wrk->who_continued.ptype; + insloc->pcopy = wrk->who_continued.pcopy; + } + } + tmp = wrk->chain; + FREE (wrk); + wrk = tmp; + } + if (!timed_out && ev_got) + *ev_got = (void *)retval; + return timed_out; +} + +/* force function print_event to be linked */ +extern void __print_event (); +static EntryPoint pev = __print_event; |