/* 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 . 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 . */ #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 (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 (INT_MAX), 0); p = static_cast (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[]) { }