diff options
Diffstat (limited to 'gcc/m2/mc-boot/GRTint.c')
-rw-r--r-- | gcc/m2/mc-boot/GRTint.c | 1122 |
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[]) +{ +} |