/* do not edit automatically generated by mc from RTint. */ /* RTint.mod provides users of the COROUTINES library with the. Copyright (C) 2009-2024 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" #include # 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_; bool 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 bool 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 ptr 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 * ptr); /* 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 (bool 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 which is associated with file descriptor, fd. */ static RTint_Vector FindVector (int fd, RTint_VectorType type); /* 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 updating max. */ static void AddFd (Selective_SetOfFd *set, int *max, int fd); /* DumpPendingQueue - displays the pending queue. */ static void DumpPendingQueue (void); /* AddTime - t1 := t1 + t2 */ static void AddTime (Selective_Timeval t1, Selective_Timeval t2); /* IsGreaterEqual - returns TRUE if, a>=b */ static bool 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 bool activatePending (bool untilInterrupt, RTint_DispatchVector call, unsigned int pri, int maxFd, Selective_SetOfFd *inSet, Selective_SetOfFd *outSet, Selective_Timeval *timeval, 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 which is associated with file descriptor, fd. */ static RTint_Vector FindVector (int fd, RTint_VectorType type) { RTint_Vector vec; vec = Exists; while (vec != NULL) { if ((vec->type == type) && (vec->File == fd)) { return vec; } vec = vec->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 vptr; vptr = Exists; while ((vptr != NULL) && (vptr->no != vec)) { vptr = vptr->exists; } return vptr; /* 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 pri; RTint_Vector vptr; for (pri=COROUTINES_UnassignedPriority; pri<=7; pri++) { vptr = Pending.array[pri-(COROUTINES_UnassignedPriority)]; while ((vptr != NULL) && (vptr->no != vec)) { vptr = vptr->pending; } if ((vptr != NULL) && (vptr->no == vec)) { return vptr; } } return NULL; /* static analysis guarentees a RETURN statement will be used before here. */ __builtin_unreachable (); } /* AddFd - adds the file descriptor fd to set updating max. */ static void AddFd (Selective_SetOfFd *set, int *max, int fd) { if (fd < 0) { return ; } (*max) = Max (fd, (*max)); if ((*set) == NULL) { (*set) = Selective_InitSet (); Selective_FdZero ((*set)); } /* printf('%d, ', fd) */ Selective_FdSet (fd, (*set)); } /* DumpPendingQueue - displays the pending queue. */ static void DumpPendingQueue (void) { COROUTINES_PROTECTION pri; RTint_Vector vptr; unsigned int sec; unsigned int micro; libc_printf ((const char *) "Pending queue\\n", 15); for (pri=COROUTINES_UnassignedPriority; pri<=7; pri++) { libc_printf ((const char *) "[%d] ", 6, pri); vptr = Pending.array[pri-(COROUTINES_UnassignedPriority)]; while (vptr != NULL) { if ((vptr->type == RTint_input) || (vptr->type == RTint_output)) { libc_printf ((const char *) "(fd=%d) (vec=%d)", 16, vptr->File, vptr->no); } else if (vptr->type == RTint_time) { /* avoid dangling else. */ Selective_GetTime (vptr->rel, &sec, µ); Assertion_Assert (micro < Microseconds); libc_printf ((const char *) "time (%u.%06u secs) (arg = %p)\\n", 32, sec, micro, vptr->arg); } vptr = vptr->pending; } libc_printf ((const char *) " \\n", 3); } } /* 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 bool 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 bool activatePending (bool untilInterrupt, RTint_DispatchVector call, unsigned int pri, int maxFd, Selective_SetOfFd *inSet, Selective_SetOfFd *outSet, Selective_Timeval *timeval, Selective_Timeval b4, Selective_Timeval after) { int result; unsigned int p; RTint_Vector vec; unsigned int b4s; unsigned int b4m; unsigned int afs; unsigned int afm; unsigned int sec; unsigned int micro; RTco_wait (lock); p = static_cast (7); while (p > pri) { vec = Pending.array[p-(COROUTINES_UnassignedPriority)]; while (vec != NULL) { switch (vec->type) { case RTint_input: if (((vec->File < maxFd) && ((*inSet) != NULL)) && (Selective_FdIsSet (vec->File, (*inSet)))) { if (Debugging) { libc_printf ((const char *) "read (fd=%d) is ready (vec=%d)\\n", 32, vec->File, vec->no); DumpPendingQueue (); } Selective_FdClr (vec->File, (*inSet)); /* so we dont activate this again from our select. */ RTco_signal (lock); /* so we dont activate this again from our select. */ (*call.proc) (vec->no, vec->priority, vec->arg); return true; } break; case RTint_output: if (((vec->File < maxFd) && ((*outSet) != NULL)) && (Selective_FdIsSet (vec->File, (*outSet)))) { if (Debugging) { libc_printf ((const char *) "write (fd=%d) is ready (vec=%d)\\n", 33, vec->File, vec->no); DumpPendingQueue (); } Selective_FdClr (vec->File, (*outSet)); /* so we dont activate this again from our select. */ RTco_signal (lock); /* so we dont activate this again from our select. */ (*call.proc) (vec->no, vec->priority, vec->arg); return true; } break; case RTint_time: if (untilInterrupt && ((*timeval) != NULL)) { result = Selective_GetTimeOfDay (after); Assertion_Assert (result == 0); if (Debugging) { Selective_GetTime ((*timeval), &sec, µ); Assertion_Assert (micro < 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, sec, micro, b4s, b4m, afs, afm); } if (IsGreaterEqual (after, vec->abs_)) { if (Debugging) { DumpPendingQueue (); libc_printf ((const char *) "time has expired calling dispatcher\\n", 37); } (*timeval) = Selective_KillTime ((*timeval)); /* 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, vec->no, vec->priority, vec->arg); } (*call.proc) (vec->no, vec->priority, vec->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/m2/gm2-libs/RTint.def", 25, 1); __builtin_unreachable (); } vec = vec->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 vptr; if (Debugging) { libc_printf ((const char *) "InitInputVector fd = %d priority = %d\\n", 39, fd, pri); } RTco_wait (lock); vptr = FindVector (fd, RTint_input); if (vptr == NULL) { Storage_ALLOCATE ((void **) &vptr, sizeof (RTint__T1)); VecNo += 1; vptr->type = RTint_input; vptr->priority = pri; vptr->arg = NULL; vptr->pending = NULL; vptr->exists = Exists; vptr->no = VecNo; vptr->File = fd; Exists = vptr; RTco_signal (lock); return VecNo; } else { RTco_signal (lock); return vptr->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 vptr; RTco_wait (lock); vptr = FindVector (fd, RTint_output); if (vptr == NULL) { Storage_ALLOCATE ((void **) &vptr, sizeof (RTint__T1)); if (vptr == NULL) { M2RTS_HALT (-1); __builtin_unreachable (); } else { VecNo += 1; vptr->type = RTint_output; vptr->priority = pri; vptr->arg = NULL; vptr->pending = NULL; vptr->exists = Exists; vptr->no = VecNo; vptr->File = fd; Exists = vptr; RTco_signal (lock); return VecNo; } } else { RTco_signal (lock); return vptr->no; } ReturnException ("../../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 vptr; RTco_wait (lock); Storage_ALLOCATE ((void **) &vptr, sizeof (RTint__T1)); if (vptr == NULL) { M2RTS_HALT (-1); __builtin_unreachable (); } else { VecNo += 1; Assertion_Assert (micro < Microseconds); vptr->type = RTint_time; vptr->priority = pri; vptr->arg = NULL; vptr->pending = NULL; vptr->exists = Exists; vptr->no = VecNo; vptr->rel = Selective_InitTime (secs+DebugTime, micro); vptr->abs_ = Selective_InitTime (0, 0); vptr->queued = false; Exists = vptr; } 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 vptr; Assertion_Assert (micro < Microseconds); RTco_wait (lock); vptr = FindVectorNo (vec); if (vptr == NULL) { M2RTS_Halt ((const char *) "cannot find vector supplied", 27, (const char *) "../../gcc/m2/gm2-libs/RTint.mod", 31, (const char *) "ReArmTimeVector", 15, 287); } else { Selective_SetTime (vptr->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 vptr; RTco_wait (lock); vptr = FindVectorNo (vec); if (vptr == NULL) { M2RTS_Halt ((const char *) "cannot find vector supplied", 27, (const char *) "../../gcc/m2/gm2-libs/RTint.mod", 31, (const char *) "GetTimeVector", 13, 313); } else { Selective_GetTime (vptr->rel, secs, micro); Assertion_Assert ((*micro) < Microseconds); } RTco_signal (lock); } /* AttachVector - adds the pointer ptr 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 * ptr) { RTint_Vector vptr; void * prevArg; RTco_wait (lock); vptr = FindVectorNo (vec); if (vptr == NULL) { M2RTS_Halt ((const char *) "cannot find vector supplied", 27, (const char *) "../../gcc/m2/gm2-libs/RTint.mod", 31, (const char *) "AttachVector", 12, 340); } else { prevArg = vptr->arg; vptr->arg = ptr; if (Debugging) { libc_printf ((const char *) "AttachVector %d with %p\\n", 25, vec, ptr); DumpPendingQueue (); } RTco_signal (lock); return prevArg; } ReturnException ("../../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 vptr; unsigned int micro; unsigned int sec; int result; RTco_wait (lock); vptr = FindPendingVector (vec); if (vptr == NULL) { /* avoid dangling else. */ vptr = FindVectorNo (vec); if (vptr == NULL) { M2RTS_Halt ((const char *) "cannot find vector supplied", 27, (const char *) "../../gcc/m2/gm2-libs/RTint.mod", 31, (const char *) "IncludeVector", 13, 374); } else { /* printf('including vector %d (fd = %d) ', vec, v^.File) ; */ vptr->pending = Pending.array[vptr->priority-(COROUTINES_UnassignedPriority)]; Pending.array[vptr->priority-(COROUTINES_UnassignedPriority)] = vptr; if ((vptr->type == RTint_time) && ! vptr->queued) { vptr->queued = true; result = Selective_GetTimeOfDay (vptr->abs_); Assertion_Assert (result == 0); Selective_GetTime (vptr->abs_, &sec, µ); Assertion_Assert (micro < Microseconds); AddTime (vptr->abs_, vptr->rel); Selective_GetTime (vptr->abs_, &sec, µ); Assertion_Assert (micro < Microseconds); } } } else { if (Debugging) { libc_printf ((const char *) "odd vector (%d) type (%d) arg (%p) is already attached to the pending queue\\n", 77, vec, vptr->type, vptr->arg); } } RTco_signal (lock); } /* ExcludeVector - excludes, vec, from the dispatcher list of possible interrupt causes. */ extern "C" void RTint_ExcludeVector (unsigned int vec) { RTint_Vector vptr; RTint_Vector uptr; RTco_wait (lock); vptr = FindPendingVector (vec); if (vptr == NULL) { M2RTS_Halt ((const char *) "cannot find pending vector supplied", 35, (const char *) "../../gcc/m2/gm2-libs/RTint.mod", 31, (const char *) "ExcludeVector", 13, 416); } else { /* printf('excluding vector %d ', vec) ; */ if (Pending.array[vptr->priority-(COROUTINES_UnassignedPriority)] == vptr) { Pending.array[vptr->priority-(COROUTINES_UnassignedPriority)] = Pending.array[vptr->priority-(COROUTINES_UnassignedPriority)]->pending; } else { uptr = Pending.array[vptr->priority-(COROUTINES_UnassignedPriority)]; while (uptr->pending != vptr) { uptr = uptr->pending; } uptr->pending = vptr->pending; } if (vptr->type == RTint_time) { vptr->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 (bool untilInterrupt, RTint_DispatchVector call, unsigned int pri) { bool found; int result; Selective_Timeval zero; Selective_Timeval after; Selective_Timeval b4; Selective_Timeval timeval; RTint_Vector vec; Selective_SetOfFd inSet; Selective_SetOfFd outSet; unsigned int sec; unsigned int micro; int maxFd; unsigned int p; RTco_wait (lock); if (pri < (7)) { if (Debugging) { DumpPendingQueue (); } maxFd = -1; timeval = NULL; inSet = NULL; outSet = NULL; timeval = Selective_InitTime (static_cast (INT_MAX), 0); p = static_cast (7); found = false; while (p > pri) { vec = Pending.array[p-(COROUTINES_UnassignedPriority)]; while (vec != NULL) { switch (vec->type) { case RTint_input: AddFd (&inSet, &maxFd, vec->File); break; case RTint_output: AddFd (&outSet, &maxFd, vec->File); break; case RTint_time: if (IsGreaterEqual (timeval, vec->abs_)) { Selective_GetTime (vec->abs_, &sec, µ); Assertion_Assert (micro < Microseconds); if (Debugging) { libc_printf ((const char *) "shortest delay is %u.%06u\\n", 27, sec, micro); } Selective_SetTime (timeval, sec, micro); found = true; } break; default: CaseException ("../../gcc/m2/gm2-libs/RTint.def", 25, 1); __builtin_unreachable (); } vec = vec->pending; } p -= 1; } if (! untilInterrupt) { Selective_SetTime (timeval, 0, 0); } if ((untilInterrupt && (((inSet == NULL) && (outSet == NULL)) || (maxFd == -1))) && ! found) { M2RTS_Halt ((const char *) "deadlock found, no more processes to run and no interrupts active", 65, (const char *) "../../gcc/m2/gm2-libs/RTint.mod", 31, (const char *) "Listen", 6, 733); } /* printf('} ') ; */ if (! found && (maxFd == -1)) { /* no file descriptors to be selected upon. */ timeval = Selective_KillTime (timeval); RTco_signal (lock); return ; } else { Selective_GetTime (timeval, &sec, µ); Assertion_Assert (micro < Microseconds); zero = Selective_InitTime (0, 0); b4 = Selective_InitTime (0, 0); after = Selective_InitTime (0, 0); result = Selective_GetTimeOfDay (b4); Assertion_Assert (result == 0); SubTime (&sec, µ, timeval, b4); Selective_SetTime (timeval, sec, micro); if (Debugging) { libc_printf ((const char *) "select waiting for %u.%06u seconds\\n", 36, sec, micro); } RTco_signal (lock); do { if (Debugging) { libc_printf ((const char *) "select (.., .., .., %u.%06u)\\n", 30, sec, micro); } if (maxFd < 0) { result = RTco_select (0, NULL, NULL, NULL, timeval); } else { result = RTco_select (maxFd+1, inSet, outSet, NULL, timeval); } if (result == -1) { if (Debugging) { libc_perror ((const char *) "select failed : ", 16); } result = RTco_select (maxFd+1, inSet, outSet, NULL, zero); if (result != -1) { Selective_GetTime (timeval, &sec, µ); if (Debugging) { libc_printf ((const char *) "(nfds : %d timeval: %u.%06u) : \\n", 33, maxFd, sec, micro); } libc_perror ((const char *) "select timeout argument was faulty : ", 37); } else { result = RTco_select (maxFd+1, inSet, NULL, NULL, timeval); if (result != -1) { libc_perror ((const char *) "select output fd argument was faulty : ", 39); } else { result = RTco_select (maxFd+1, NULL, outSet, NULL, timeval); if (result != -1) { libc_perror ((const char *) "select input fd argument was faulty : ", 38); } else { if (maxFd == -1) { /* avoid dangling else. */ result = RTco_select (0, NULL, NULL, NULL, timeval); if (result == -1) { if (Debugging) { libc_perror ((const char *) "select does not accept nfds == 0 ", 33); } result = 0; } } else { libc_perror ((const char *) "select maxFD+1 argument was faulty : ", 37); } } } } } } while (! (result != -1)); } while (activatePending (untilInterrupt, call, pri, maxFd+1, &inSet, &outSet, &timeval, b4, after)) {} /* empty. */ if (timeval != NULL) { timeval = Selective_KillTime (timeval); } if (zero != NULL) { zero = Selective_KillTime (zero); } if (after != NULL) { after = Selective_KillTime (after); } if (b4 != NULL) { b4 = Selective_KillTime (b4); } if (inSet != NULL) { inSet = Selective_KillSet (inSet); } if (outSet != NULL) { outSet = Selective_KillSet (outSet); } } 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_fini (__attribute__((unused)) int argc,__attribute__((unused)) char *argv[],__attribute__((unused)) char *envp[]) { }