aboutsummaryrefslogtreecommitdiff
path: root/gcc/m2/mc-boot/GRTint.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/m2/mc-boot/GRTint.c')
-rw-r--r--gcc/m2/mc-boot/GRTint.c1122
1 files changed, 1122 insertions, 0 deletions
diff --git a/gcc/m2/mc-boot/GRTint.c b/gcc/m2/mc-boot/GRTint.c
new file mode 100644
index 0000000..fd73d32
--- /dev/null
+++ b/gcc/m2/mc-boot/GRTint.c
@@ -0,0 +1,1122 @@
+/* do not edit automatically generated by mc from RTint. */
+/* RTint.mod provides users of the COROUTINES library with the.
+
+Copyright (C) 2009-2021 Free Software Foundation, Inc.
+Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
+
+This file is part of GNU Modula-2.
+
+GNU Modula-2 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 3, or (at your option)
+any later version.
+
+GNU Modula-2 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.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+# if !defined (PROC_D)
+# define PROC_D
+ typedef void (*PROC_t) (void);
+ typedef struct { PROC_t proc; } PROC;
+# endif
+
+# if !defined (TRUE)
+# define TRUE (1==1)
+# endif
+
+# if !defined (FALSE)
+# define FALSE (1==0)
+# endif
+
+# include "GStorage.h"
+# include "Gmcrts.h"
+#if defined(__cplusplus)
+# undef NULL
+# define NULL 0
+#endif
+#define _RTint_H
+#define _RTint_C
+
+# include "GM2RTS.h"
+# include "GStorage.h"
+# include "GRTco.h"
+# include "GCOROUTINES.h"
+# include "Glibc.h"
+# include "GAssertion.h"
+# include "GSelective.h"
+
+typedef struct RTint_DispatchVector_p RTint_DispatchVector;
+
+# define Microseconds 1000000
+# define DebugTime 0
+# define Debugging FALSE
+typedef struct RTint__T1_r RTint__T1;
+
+typedef RTint__T1 *RTint_Vector;
+
+typedef struct RTint__T2_a RTint__T2;
+
+typedef enum {RTint_input, RTint_output, RTint_time} RTint_VectorType;
+
+typedef void (*RTint_DispatchVector_t) (unsigned int, unsigned int, void *);
+struct RTint_DispatchVector_p { RTint_DispatchVector_t proc; };
+
+struct RTint__T1_r {
+ RTint_VectorType type;
+ unsigned int priority;
+ void *arg;
+ RTint_Vector pending;
+ RTint_Vector exists;
+ unsigned int no;
+ int File;
+ Selective_Timeval rel;
+ Selective_Timeval abs_;
+ unsigned int queued;
+ };
+
+struct RTint__T2_a { RTint_Vector array[(7)-(COROUTINES_UnassignedPriority)+1]; };
+static unsigned int VecNo;
+static RTint_Vector Exists;
+static RTint__T2 Pending;
+static int lock;
+static unsigned int initialized;
+
+/*
+ InitInputVector - returns an interrupt vector which is associated
+ with the file descriptor, fd.
+*/
+
+extern "C" unsigned int RTint_InitInputVector (int fd, unsigned int pri);
+
+/*
+ InitOutputVector - returns an interrupt vector which is associated
+ with the file descriptor, fd.
+*/
+
+extern "C" unsigned int RTint_InitOutputVector (int fd, unsigned int pri);
+
+/*
+ InitTimeVector - returns an interrupt vector associated with
+ the relative time.
+*/
+
+extern "C" unsigned int RTint_InitTimeVector (unsigned int micro, unsigned int secs, unsigned int pri);
+
+/*
+ ReArmTimeVector - reprimes the vector, vec, to deliver an interrupt
+ at the new relative time.
+*/
+
+extern "C" void RTint_ReArmTimeVector (unsigned int vec, unsigned int micro, unsigned int secs);
+
+/*
+ GetTimeVector - assigns, micro, and, secs, with the remaining
+ time before this interrupt will expire.
+ This value is only updated when a Listen
+ occurs.
+*/
+
+extern "C" void RTint_GetTimeVector (unsigned int vec, unsigned int *micro, unsigned int *secs);
+
+/*
+ AttachVector - adds the pointer, p, to be associated with the interrupt
+ vector. It returns the previous value attached to this
+ vector.
+*/
+
+extern "C" void * RTint_AttachVector (unsigned int vec, void * p);
+
+/*
+ IncludeVector - includes, vec, into the dispatcher list of
+ possible interrupt causes.
+*/
+
+extern "C" void RTint_IncludeVector (unsigned int vec);
+
+/*
+ ExcludeVector - excludes, vec, from the dispatcher list of
+ possible interrupt causes.
+*/
+
+extern "C" void RTint_ExcludeVector (unsigned int vec);
+
+/*
+ Listen - will either block indefinitely (until an interrupt)
+ or alteratively will test to see whether any interrupts
+ are pending.
+ If a pending interrupt was found then, call, is called
+ and then this procedure returns.
+ It only listens for interrupts > pri.
+*/
+
+extern "C" void RTint_Listen (unsigned int untilInterrupt, RTint_DispatchVector call, unsigned int pri);
+
+/*
+ Init -
+*/
+
+extern "C" void RTint_Init (void);
+
+/*
+ Max - returns the maximum: i or j.
+*/
+
+static int Max (int i, int j);
+static int Min (int i, int j);
+
+/*
+ FindVector - searches the exists list for a vector of type, t,
+ which is associated with file descriptor, fd.
+*/
+
+static RTint_Vector FindVector (int fd, RTint_VectorType t);
+
+/*
+ FindVectorNo - searches the Exists list for vector, vec.
+*/
+
+static RTint_Vector FindVectorNo (unsigned int vec);
+
+/*
+ FindPendingVector - searches the pending list for vector, vec.
+*/
+
+static RTint_Vector FindPendingVector (unsigned int vec);
+
+/*
+ AddFd - adds the file descriptor, fd, to set, s, updating, max.
+*/
+
+static void AddFd (Selective_SetOfFd *s, int *max, int fd);
+
+/*
+ DumpPendingQueue - displays the pending queue.
+*/
+
+static void DumpPendingQueue (void);
+
+/*
+ DumpPendingQueue - displays the pending queue.
+*/
+
+static void stop (void);
+
+/*
+ AddTime - t1 := t1 + t2
+*/
+
+static void AddTime (Selective_Timeval t1, Selective_Timeval t2);
+
+/*
+ IsGreaterEqual - returns TRUE if, a>=b
+*/
+
+static unsigned int IsGreaterEqual (Selective_Timeval a, Selective_Timeval b);
+
+/*
+ SubTime - assigns, s and m, to a - b.
+*/
+
+static void SubTime (unsigned int *s, unsigned int *m, Selective_Timeval a, Selective_Timeval b);
+
+/*
+ activatePending - activates the first interrupt pending and clears it.
+*/
+
+static unsigned int activatePending (unsigned int untilInterrupt, RTint_DispatchVector call, unsigned int pri, int maxFd, Selective_SetOfFd *i, Selective_SetOfFd *o, Selective_Timeval *t, Selective_Timeval b4, Selective_Timeval after);
+
+/*
+ init -
+*/
+
+static void init (void);
+
+
+/*
+ Max - returns the maximum: i or j.
+*/
+
+static int Max (int i, int j)
+{
+ if (i > j)
+ {
+ return i;
+ }
+ else
+ {
+ return j;
+ }
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+static int Min (int i, int j)
+{
+ /*
+ Max - returns the minimum: i or j.
+ */
+ if (i < j)
+ {
+ return i;
+ }
+ else
+ {
+ return j;
+ }
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ FindVector - searches the exists list for a vector of type, t,
+ which is associated with file descriptor, fd.
+*/
+
+static RTint_Vector FindVector (int fd, RTint_VectorType t)
+{
+ RTint_Vector v;
+
+ v = Exists;
+ while (v != NULL)
+ {
+ if ((v->type == t) && (v->File == fd))
+ {
+ return v;
+ }
+ v = v->exists;
+ }
+ return NULL;
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ FindVectorNo - searches the Exists list for vector, vec.
+*/
+
+static RTint_Vector FindVectorNo (unsigned int vec)
+{
+ RTint_Vector v;
+
+ v = Exists;
+ while ((v != NULL) && (v->no != vec))
+ {
+ v = v->exists;
+ }
+ return v;
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ FindPendingVector - searches the pending list for vector, vec.
+*/
+
+static RTint_Vector FindPendingVector (unsigned int vec)
+{
+ unsigned int i;
+ RTint_Vector v;
+
+ for (i=COROUTINES_UnassignedPriority; i<=7; i++)
+ {
+ v = Pending.array[i-(COROUTINES_UnassignedPriority)];
+ while ((v != NULL) && (v->no != vec))
+ {
+ v = v->pending;
+ }
+ if ((v != NULL) && (v->no == vec))
+ {
+ return v;
+ }
+ }
+ return NULL;
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ AddFd - adds the file descriptor, fd, to set, s, updating, max.
+*/
+
+static void AddFd (Selective_SetOfFd *s, int *max, int fd)
+{
+ (*max) = Max (fd, (*max));
+ if ((*s) == NULL)
+ {
+ (*s) = Selective_InitSet ();
+ Selective_FdZero ((*s));
+ }
+ /* printf('%d, ', fd) */
+ Selective_FdSet (fd, (*s));
+}
+
+
+/*
+ DumpPendingQueue - displays the pending queue.
+*/
+
+static void DumpPendingQueue (void)
+{
+ COROUTINES_PROTECTION p;
+ RTint_Vector v;
+ unsigned int s;
+ unsigned int m;
+
+ libc_printf ((const char *) "Pending queue\\n", 15);
+ for (p=COROUTINES_UnassignedPriority; p<=7; p++)
+ {
+ libc_printf ((const char *) "[%d] ", 6, p);
+ v = Pending.array[p-(COROUTINES_UnassignedPriority)];
+ while (v != NULL)
+ {
+ if ((v->type == RTint_input) || (v->type == RTint_output))
+ {
+ libc_printf ((const char *) "(fd=%d) (vec=%d)", 16, v->File, v->no);
+ }
+ else if (v->type == RTint_time)
+ {
+ /* avoid dangling else. */
+ Selective_GetTime (v->rel, &s, &m);
+ Assertion_Assert (m < Microseconds);
+ libc_printf ((const char *) "time (%u.%06u secs) (arg = 0x%x)\\n", 34, s, m, v->arg);
+ }
+ v = v->pending;
+ }
+ libc_printf ((const char *) " \\n", 3);
+ }
+}
+
+
+/*
+ DumpPendingQueue - displays the pending queue.
+*/
+
+static void stop (void)
+{
+}
+
+
+/*
+ AddTime - t1 := t1 + t2
+*/
+
+static void AddTime (Selective_Timeval t1, Selective_Timeval t2)
+{
+ unsigned int a;
+ unsigned int b;
+ unsigned int s;
+ unsigned int m;
+
+ Selective_GetTime (t1, &s, &m);
+ Assertion_Assert (m < Microseconds);
+ Selective_GetTime (t2, &a, &b);
+ Assertion_Assert (b < Microseconds);
+ a += s;
+ b += m;
+ if (b >= Microseconds)
+ {
+ b -= Microseconds;
+ a += 1;
+ }
+ Selective_SetTime (t1, a, b);
+}
+
+
+/*
+ IsGreaterEqual - returns TRUE if, a>=b
+*/
+
+static unsigned int IsGreaterEqual (Selective_Timeval a, Selective_Timeval b)
+{
+ unsigned int as;
+ unsigned int am;
+ unsigned int bs;
+ unsigned int bm;
+
+ Selective_GetTime (a, &as, &am);
+ Assertion_Assert (am < Microseconds);
+ Selective_GetTime (b, &bs, &bm);
+ Assertion_Assert (bm < Microseconds);
+ return (as > bs) || ((as == bs) && (am >= bm));
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ SubTime - assigns, s and m, to a - b.
+*/
+
+static void SubTime (unsigned int *s, unsigned int *m, Selective_Timeval a, Selective_Timeval b)
+{
+ unsigned int as;
+ unsigned int am;
+ unsigned int bs;
+ unsigned int bm;
+
+ Selective_GetTime (a, &as, &am);
+ Assertion_Assert (am < Microseconds);
+ Selective_GetTime (b, &bs, &bm);
+ Assertion_Assert (bm < Microseconds);
+ if (IsGreaterEqual (a, b))
+ {
+ (*s) = as-bs;
+ if (am >= bm)
+ {
+ (*m) = am-bm;
+ Assertion_Assert ((*m) < Microseconds);
+ }
+ else
+ {
+ Assertion_Assert ((*s) > 0);
+ (*s) -= 1;
+ (*m) = (Microseconds+am)-bm;
+ Assertion_Assert ((*m) < Microseconds);
+ }
+ }
+ else
+ {
+ (*s) = 0;
+ (*m) = 0;
+ }
+}
+
+
+/*
+ activatePending - activates the first interrupt pending and clears it.
+*/
+
+static unsigned int activatePending (unsigned int untilInterrupt, RTint_DispatchVector call, unsigned int pri, int maxFd, Selective_SetOfFd *i, Selective_SetOfFd *o, Selective_Timeval *t, Selective_Timeval b4, Selective_Timeval after)
+{
+ int r;
+ unsigned int p;
+ RTint_Vector v;
+ unsigned int b4s;
+ unsigned int b4m;
+ unsigned int afs;
+ unsigned int afm;
+ unsigned int s;
+ unsigned int m;
+
+ RTco_wait (lock);
+ p = static_cast<unsigned int> (7);
+ while (p > pri)
+ {
+ v = Pending.array[p-(COROUTINES_UnassignedPriority)];
+ while (v != NULL)
+ {
+ switch (v->type)
+ {
+ case RTint_input:
+ if (((v->File < maxFd) && ((*i) != NULL)) && (Selective_FdIsSet (v->File, (*i))))
+ {
+ if (Debugging)
+ {
+ libc_printf ((const char *) "read (fd=%d) is ready (vec=%d)\\n", 32, v->File, v->no);
+ DumpPendingQueue ();
+ }
+ Selective_FdClr (v->File, (*i)); /* so we dont activate this again from our select. */
+ RTco_signal (lock); /* so we dont activate this again from our select. */
+ (*call.proc) (v->no, v->priority, v->arg);
+ return TRUE;
+ }
+ break;
+
+ case RTint_output:
+ if (((v->File < maxFd) && ((*o) != NULL)) && (Selective_FdIsSet (v->File, (*o))))
+ {
+ if (Debugging)
+ {
+ libc_printf ((const char *) "write (fd=%d) is ready (vec=%d)\\n", 33, v->File, v->no);
+ DumpPendingQueue ();
+ }
+ Selective_FdClr (v->File, (*o)); /* so we dont activate this again from our select. */
+ RTco_signal (lock); /* so we dont activate this again from our select. */
+ (*call.proc) (v->no, v->priority, v->arg);
+ return TRUE;
+ }
+ break;
+
+ case RTint_time:
+ if (untilInterrupt && ((*t) != NULL))
+ {
+ r = Selective_GetTimeOfDay (after);
+ Assertion_Assert (r == 0);
+ if (Debugging)
+ {
+ Selective_GetTime ((*t), &s, &m);
+ Assertion_Assert (m < Microseconds);
+ Selective_GetTime (after, &afs, &afm);
+ Assertion_Assert (afm < Microseconds);
+ Selective_GetTime (b4, &b4s, &b4m);
+ Assertion_Assert (b4m < Microseconds);
+ libc_printf ((const char *) "waited %u.%06u + %u.%06u now is %u.%06u\\n", 41, s, m, b4s, b4m, afs, afm);
+ }
+ if (IsGreaterEqual (after, v->abs_))
+ {
+ if (Debugging)
+ {
+ DumpPendingQueue ();
+ libc_printf ((const char *) "time has expired calling dispatcher\\n", 37);
+ }
+ (*t) = Selective_KillTime ((*t)); /* so we dont activate this again from our select. */
+ RTco_signal (lock); /* so we dont activate this again from our select. */
+ if (Debugging)
+ {
+ libc_printf ((const char *) "call (%d, %d, 0x%x)\\n", 21, v->no, v->priority, v->arg);
+ }
+ (*call.proc) (v->no, v->priority, v->arg);
+ return TRUE;
+ }
+ else if (Debugging)
+ {
+ /* avoid dangling else. */
+ libc_printf ((const char *) "must wait longer as time has not expired\\n", 42);
+ }
+ }
+ break;
+
+
+ default:
+ CaseException ("../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.def", 25, 1);
+ __builtin_unreachable ();
+ }
+ v = v->pending;
+ }
+ p -= 1;
+ }
+ RTco_signal (lock);
+ return FALSE;
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ init -
+*/
+
+static void init (void)
+{
+ COROUTINES_PROTECTION p;
+
+ lock = RTco_initSemaphore (1);
+ RTco_wait (lock);
+ Exists = NULL;
+ for (p=COROUTINES_UnassignedPriority; p<=7; p++)
+ {
+ Pending.array[p-(COROUTINES_UnassignedPriority)] = NULL;
+ }
+ initialized = TRUE;
+ RTco_signal (lock);
+}
+
+
+/*
+ InitInputVector - returns an interrupt vector which is associated
+ with the file descriptor, fd.
+*/
+
+extern "C" unsigned int RTint_InitInputVector (int fd, unsigned int pri)
+{
+ RTint_Vector v;
+
+ if (Debugging)
+ {
+ libc_printf ((const char *) "InitInputVector fd = %d priority = %d\\n", 39, fd, pri);
+ }
+ RTco_wait (lock);
+ v = FindVector (fd, RTint_input);
+ if (v == NULL)
+ {
+ Storage_ALLOCATE ((void **) &v, sizeof (RTint__T1));
+ VecNo += 1;
+ v->type = RTint_input;
+ v->priority = pri;
+ v->arg = NULL;
+ v->pending = NULL;
+ v->exists = Exists;
+ v->no = VecNo;
+ v->File = fd;
+ Exists = v;
+ RTco_signal (lock);
+ return VecNo;
+ }
+ else
+ {
+ RTco_signal (lock);
+ return v->no;
+ }
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ InitOutputVector - returns an interrupt vector which is associated
+ with the file descriptor, fd.
+*/
+
+extern "C" unsigned int RTint_InitOutputVector (int fd, unsigned int pri)
+{
+ RTint_Vector v;
+
+ RTco_wait (lock);
+ v = FindVector (fd, RTint_output);
+ if (v == NULL)
+ {
+ Storage_ALLOCATE ((void **) &v, sizeof (RTint__T1));
+ if (v == NULL)
+ {
+ M2RTS_HALT (-1);
+ __builtin_unreachable ();
+ }
+ else
+ {
+ VecNo += 1;
+ v->type = RTint_output;
+ v->priority = pri;
+ v->arg = NULL;
+ v->pending = NULL;
+ v->exists = Exists;
+ v->no = VecNo;
+ v->File = fd;
+ Exists = v;
+ RTco_signal (lock);
+ return VecNo;
+ }
+ }
+ else
+ {
+ RTco_signal (lock);
+ return v->no;
+ }
+ ReturnException ("../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.def", 25, 1);
+ __builtin_unreachable ();
+}
+
+
+/*
+ InitTimeVector - returns an interrupt vector associated with
+ the relative time.
+*/
+
+extern "C" unsigned int RTint_InitTimeVector (unsigned int micro, unsigned int secs, unsigned int pri)
+{
+ RTint_Vector v;
+
+ RTco_wait (lock);
+ Storage_ALLOCATE ((void **) &v, sizeof (RTint__T1));
+ if (v == NULL)
+ {
+ M2RTS_HALT (-1);
+ __builtin_unreachable ();
+ }
+ else
+ {
+ VecNo += 1;
+ Assertion_Assert (micro < Microseconds);
+ v->type = RTint_time;
+ v->priority = pri;
+ v->arg = NULL;
+ v->pending = NULL;
+ v->exists = Exists;
+ v->no = VecNo;
+ v->rel = Selective_InitTime (secs+DebugTime, micro);
+ v->abs_ = Selective_InitTime (0, 0);
+ v->queued = FALSE;
+ Exists = v;
+ }
+ RTco_signal (lock);
+ return VecNo;
+ /* static analysis guarentees a RETURN statement will be used before here. */
+ __builtin_unreachable ();
+}
+
+
+/*
+ ReArmTimeVector - reprimes the vector, vec, to deliver an interrupt
+ at the new relative time.
+*/
+
+extern "C" void RTint_ReArmTimeVector (unsigned int vec, unsigned int micro, unsigned int secs)
+{
+ RTint_Vector v;
+
+ Assertion_Assert (micro < Microseconds);
+ RTco_wait (lock);
+ v = FindVectorNo (vec);
+ if (v == NULL)
+ {
+ M2RTS_Halt ((const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.mod", 53, 286, (const char *) "ReArmTimeVector", 15, (const char *) "cannot find vector supplied", 27);
+ }
+ else
+ {
+ Selective_SetTime (v->rel, secs+DebugTime, micro);
+ }
+ RTco_signal (lock);
+}
+
+
+/*
+ GetTimeVector - assigns, micro, and, secs, with the remaining
+ time before this interrupt will expire.
+ This value is only updated when a Listen
+ occurs.
+*/
+
+extern "C" void RTint_GetTimeVector (unsigned int vec, unsigned int *micro, unsigned int *secs)
+{
+ RTint_Vector v;
+
+ RTco_wait (lock);
+ v = FindVectorNo (vec);
+ if (v == NULL)
+ {
+ M2RTS_Halt ((const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.mod", 53, 312, (const char *) "GetTimeVector", 13, (const char *) "cannot find vector supplied", 27);
+ }
+ else
+ {
+ Selective_GetTime (v->rel, secs, micro);
+ Assertion_Assert ((*micro) < Microseconds);
+ }
+ RTco_signal (lock);
+}
+
+
+/*
+ AttachVector - adds the pointer, p, to be associated with the interrupt
+ vector. It returns the previous value attached to this
+ vector.
+*/
+
+extern "C" void * RTint_AttachVector (unsigned int vec, void * p)
+{
+ RTint_Vector v;
+ void * l;
+
+ RTco_wait (lock);
+ v = FindVectorNo (vec);
+ if (v == NULL)
+ {
+ M2RTS_Halt ((const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.mod", 53, 339, (const char *) "AttachVector", 12, (const char *) "cannot find vector supplied", 27);
+ }
+ else
+ {
+ l = v->arg;
+ v->arg = p;
+ if (Debugging)
+ {
+ libc_printf ((const char *) "AttachVector %d with 0x%x\\n", 27, vec, p);
+ DumpPendingQueue ();
+ }
+ RTco_signal (lock);
+ return l;
+ }
+ ReturnException ("../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.def", 25, 1);
+ __builtin_unreachable ();
+}
+
+
+/*
+ IncludeVector - includes, vec, into the dispatcher list of
+ possible interrupt causes.
+*/
+
+extern "C" void RTint_IncludeVector (unsigned int vec)
+{
+ RTint_Vector v;
+ unsigned int m;
+ unsigned int s;
+ int r;
+
+ RTco_wait (lock);
+ v = FindPendingVector (vec);
+ if (v == NULL)
+ {
+ /* avoid dangling else. */
+ v = FindVectorNo (vec);
+ if (v == NULL)
+ {
+ M2RTS_Halt ((const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.mod", 53, 372, (const char *) "IncludeVector", 13, (const char *) "cannot find vector supplied", 27);
+ }
+ else
+ {
+ /* printf('including vector %d (fd = %d)
+ ', vec, v^.File) ; */
+ v->pending = Pending.array[v->priority-(COROUTINES_UnassignedPriority)];
+ Pending.array[v->priority-(COROUTINES_UnassignedPriority)] = v;
+ if ((v->type == RTint_time) && ! v->queued)
+ {
+ v->queued = TRUE;
+ r = Selective_GetTimeOfDay (v->abs_);
+ Assertion_Assert (r == 0);
+ Selective_GetTime (v->abs_, &s, &m);
+ Assertion_Assert (m < Microseconds);
+ AddTime (v->abs_, v->rel);
+ Selective_GetTime (v->abs_, &s, &m);
+ Assertion_Assert (m < Microseconds);
+ }
+ }
+ }
+ else
+ {
+ if (Debugging)
+ {
+ libc_printf ((const char *) "odd vector (%d) type (%d) arg (0x%x) is already attached to the pending queue\\n", 79, vec, v->type, v->arg);
+ }
+ stop ();
+ }
+ RTco_signal (lock);
+}
+
+
+/*
+ ExcludeVector - excludes, vec, from the dispatcher list of
+ possible interrupt causes.
+*/
+
+extern "C" void RTint_ExcludeVector (unsigned int vec)
+{
+ RTint_Vector v;
+ RTint_Vector u;
+
+ RTco_wait (lock);
+ v = FindPendingVector (vec);
+ if (v == NULL)
+ {
+ M2RTS_Halt ((const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.mod", 53, 415, (const char *) "ExcludeVector", 13, (const char *) "cannot find pending vector supplied", 35);
+ }
+ else
+ {
+ /* printf('excluding vector %d
+ ', vec) ; */
+ if (Pending.array[v->priority-(COROUTINES_UnassignedPriority)] == v)
+ {
+ Pending.array[v->priority-(COROUTINES_UnassignedPriority)] = Pending.array[v->priority-(COROUTINES_UnassignedPriority)]->pending;
+ }
+ else
+ {
+ u = Pending.array[v->priority-(COROUTINES_UnassignedPriority)];
+ while (u->pending != v)
+ {
+ u = u->pending;
+ }
+ u->pending = v->pending;
+ }
+ if (v->type == RTint_time)
+ {
+ v->queued = FALSE;
+ }
+ }
+ RTco_signal (lock);
+}
+
+
+/*
+ Listen - will either block indefinitely (until an interrupt)
+ or alteratively will test to see whether any interrupts
+ are pending.
+ If a pending interrupt was found then, call, is called
+ and then this procedure returns.
+ It only listens for interrupts > pri.
+*/
+
+extern "C" void RTint_Listen (unsigned int untilInterrupt, RTint_DispatchVector call, unsigned int pri)
+{
+ unsigned int found;
+ int r;
+ Selective_Timeval after;
+ Selective_Timeval b4;
+ Selective_Timeval t;
+ RTint_Vector v;
+ Selective_SetOfFd i;
+ Selective_SetOfFd o;
+ unsigned int b4s;
+ unsigned int b4m;
+ unsigned int afs;
+ unsigned int afm;
+ unsigned int s;
+ unsigned int m;
+ int maxFd;
+ unsigned int p;
+
+ RTco_wait (lock);
+ if (pri < (7))
+ {
+ if (Debugging)
+ {
+ DumpPendingQueue ();
+ }
+ maxFd = -1;
+ t = NULL;
+ i = NULL;
+ o = NULL;
+ t = Selective_InitTime (static_cast<unsigned int> (INT_MAX), 0);
+ p = static_cast<unsigned int> (7);
+ found = FALSE;
+ while (p > pri)
+ {
+ v = Pending.array[p-(COROUTINES_UnassignedPriority)];
+ while (v != NULL)
+ {
+ switch (v->type)
+ {
+ case RTint_input:
+ AddFd (&i, &maxFd, v->File);
+ break;
+
+ case RTint_output:
+ AddFd (&o, &maxFd, v->File);
+ break;
+
+ case RTint_time:
+ if (IsGreaterEqual (t, v->abs_))
+ {
+ Selective_GetTime (v->abs_, &s, &m);
+ Assertion_Assert (m < Microseconds);
+ if (Debugging)
+ {
+ libc_printf ((const char *) "shortest delay is %u.%06u\\n", 27, s, m);
+ }
+ Selective_SetTime (t, s, m);
+ found = TRUE;
+ }
+ break;
+
+
+ default:
+ CaseException ("../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.def", 25, 1);
+ __builtin_unreachable ();
+ }
+ v = v->pending;
+ }
+ p -= 1;
+ }
+ if (! untilInterrupt)
+ {
+ Selective_SetTime (t, 0, 0);
+ }
+ if (((untilInterrupt && (i == NULL)) && (o == NULL)) && ! found)
+ {
+ M2RTS_Halt ((const char *) "../../gcc-git-devel-modula2/gcc/m2/gm2-libs/RTint.mod", 53, 731, (const char *) "Listen", 6, (const char *) "deadlock found, no more processes to run and no interrupts active", 65);
+ }
+ /* printf('}
+ ') ; */
+ if (((! found && (maxFd == -1)) && (i == NULL)) && (o == NULL))
+ {
+ /* no file descriptors to be selected upon. */
+ t = Selective_KillTime (t);
+ RTco_signal (lock);
+ return ;
+ }
+ else
+ {
+ Selective_GetTime (t, &s, &m);
+ Assertion_Assert (m < Microseconds);
+ b4 = Selective_InitTime (0, 0);
+ after = Selective_InitTime (0, 0);
+ r = Selective_GetTimeOfDay (b4);
+ Assertion_Assert (r == 0);
+ SubTime (&s, &m, t, b4);
+ Selective_SetTime (t, s, m);
+ if (Debugging)
+ {
+ libc_printf ((const char *) "select waiting for %u.%06u seconds\\n", 36, s, m);
+ }
+ RTco_signal (lock);
+ do {
+ if (Debugging)
+ {
+ libc_printf ((const char *) "select (.., .., .., %u.%06u)\\n", 30, s, m);
+ }
+ r = RTco_select (maxFd+1, i, o, NULL, t);
+ if (r == -1)
+ {
+ libc_perror ((const char *) "select", 6);
+ r = RTco_select (maxFd+1, i, o, NULL, NULL);
+ if (r == -1)
+ {
+ libc_perror ((const char *) "select timeout argument is faulty", 33);
+ }
+ r = RTco_select (maxFd+1, i, NULL, NULL, t);
+ if (r == -1)
+ {
+ libc_perror ((const char *) "select output fd argument is faulty", 35);
+ }
+ r = RTco_select (maxFd+1, NULL, o, NULL, t);
+ if (r == -1)
+ {
+ libc_perror ((const char *) "select input fd argument is faulty", 34);
+ }
+ else
+ {
+ libc_perror ((const char *) "select maxFD+1 argument is faulty", 33);
+ }
+ }
+ } while (! (r != -1));
+ }
+ while (activatePending (untilInterrupt, call, pri, maxFd+1, &i, &o, &t, b4, after))
+ {} /* empty. */
+ if (t != NULL)
+ {
+ t = Selective_KillTime (t);
+ }
+ if (after != NULL)
+ {
+ t = Selective_KillTime (after);
+ }
+ if (b4 != NULL)
+ {
+ t = Selective_KillTime (b4);
+ }
+ if (i != NULL)
+ {
+ i = Selective_KillSet (i);
+ }
+ if (o != NULL)
+ {
+ o = Selective_KillSet (o);
+ }
+ }
+ RTco_signal (lock);
+}
+
+
+/*
+ Init -
+*/
+
+extern "C" void RTint_Init (void)
+{
+ if (! initialized)
+ {
+ init ();
+ }
+}
+
+extern "C" void _M2_RTint_init (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
+{
+ RTint_Init ();
+}
+
+extern "C" void _M2_RTint_finish (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[])
+{
+}