/* * sThreads.c -- stubbed out PCR * * July 6, 1993 - mfp * XR←PauseAbortable fixed to set the return value as specified in Threads.h */ #include <xr/Threads.h> #include <xr/ThreadsDynamicEnvironment.h> #include <xr/sMisc.h> #include <sys/param.h> #include <sys/types.h> #include <sys/time.h> #include <stdlib.h> #include <errno.h> extern char **envp; static long bootTime; struct XR←ThreadRep theOnlyThread; XR←Thread XR←currThread = &theOnlyThread; void SPCR←Init() { extern int SPCR←debugMessages; (void) time(&bootTime); if (getenv("SPCR←DEBUG")) SPCR←debugMessages = 1; GC←register←displacement(8); } struct cu←info { void (**cu←proc)(); XR←Pointer cu←data; }; struct cu←info * cleanupInfo; static void generic←cu←proc() { (**(cleanupInfo -> cu←proc))(cleanupInfo -> cu←data); } int XR←RegisterTerminationCleanupProc(proc, clientData) void (**proc)(); XR←Pointer clientData; { cleanupInfo = (struct cu←info *) GC←malloc(sizeof (struct cu←info)); if (cleanupInfo == 0) { errno = ENOMEM; return(-1); } cleanupInfo -> cu←proc = proc; cleanupInfo -> cu←data = clientData; return(atexit(generic←cu←proc)); } XR←Ticks XR←TicksSinceBoot() { return (time(0) - bootTime) * XR←TICKS←PER←SECOND; } #undef XR←TicksToMsec unsigned XR←TicksToMsec(ticks) XR←Ticks ticks; { return ticks * XR←MSECS←PER←TICK; } #undef XR←MsecToTicks XR←Ticks XR←MsecToTicks(msec) unsigned msec; { return msec / XR←MSECS←PER←TICK; } void XR←InitializeCondition(cv, timeout) XR←CV cv; XR←Ticks timeout; { cv->cv←timeout = timeout; SPCR←NotImplemented("InitializeCondition"); } void XR←InitializeMonitor(ml) XR←ML ml; { ml->ml←holder = 0; } void XR←MonitorEntry(ml) XR←ML ml; { if (ml->ml←holder) { SPCR←error("Deadlock!\n"); } ml->ml←holder = XR←currThread; } void XR←MonitorExit(ml) XR←ML ml; { ml->ml←holder = 0; } void XR←SetTimeout(cv, timeout) XR←CV cv; XR←Ticks timeout; { cv->cv←timeout = timeout; } void XR←DisableTimeout(cv) XR←CV cv; { cv->cv←timeout = XR←WAIT←FOREVER; } void XR←DisableAborts(cv) XR←CV cv; { } void XR←EnableAborts(cv) XR←CV cv; { cv->cv←abortable = TRUE; } bool XR←AbortPending () { return( FALSE ); } int XR←WaitCV(cv, ml) XR←CV cv; XR←ML ml; { if (cv->cv←timeout != XR←WAIT←FOREVER) sleep(XR←TicksToMsec(cv->cv←timeout)/1000); else { SPCR←error("Waiting forever w/o timeout in a single-process world"); } return 0; } int XR←ValidateCT(ct) XR←CT ct; { return (ct->ct←thread == XR←currThread) ? 0 : -1; } void XR←Notify(cv) XR←CV cv; { } void XR←Broadcast(ct) XR←CT ct; { } void XR←UplevelSetjmp(jb) XR←JmpBuf jb; { SPCR←NotImplemented("XR←UplevelSetJmp"); } XR←DBMsg XR←CallDebugger(arg) XR←Pointer arg; { SPCR←error("Debugger Called\n"); } XR←Pointer XR←ExtensionFree(x) XR←Pointer x; { return NIL; } static current←pri = 3; /* NORMAL */ #undef XR←GetPriority XR←Pri XR←GetPriority() { return(current←pri); } void XR←SetPriority(pri) XR←Pri pri; { current←pri = pri; } void XR←Yield() { } void XR←GetCurrent(result) struct XR←CTRep *result; { result->ct←thread = XR←currThread; result -> ct←gen = 1; } void XR←Fork(result, mp) struct XR←CTRep *result; XR←MesaProc mp; { SPCR←NotImplemented("XR←Fork"); } XR←Pointer XR←JoinCT(ct) XR←CT ct; { SPCR←NotImplemented("XR←JoinCT"); return -1; } int XR←PauseAbortable(ticks) XR←Ticks ticks; { struct timeval timeout; unsigned long msec = XR←TicksToMsec(ticks); timeout.tv←sec = msec/1000; timeout.tv←usec = (msec % 1000) * 1000; return (select(0,0,0,0, &timeout)); } int XR←CancelAbort(ct) XR←CT ct; { return 0; } int XR←DetachCT(ct) XR←CT ct; { SPCR←NotImplemented("XR←DetachCT"); return 0; } int XR←AbortCT(ct) XR←CT ct; { SPCR←NotImplemented("XR←AbortCT"); return 0; } void XR←ExitWorld(status) int status; { ←exit(status); } void XR←RestartHandlee(t, where, result) /* !!!! no declaration in .h */ XR←Thread t; jmp←buf where; unsigned result; { if( t == NIL ) t = XR←currThread; else if( t != XR←currThread ) { SPCR←error("Current Thread isn't only thread!"); } if( where == NIL ) { SPCR←error("Handlee jumpbuf is NIL!"); } XR←longjmp( where, result ); } XR←Thread XR←GetNextHandlee(t) /* !!!! no declaration in .h */ XR←Thread t; { if( t == NIL ) return ( XR←currThread ); SPCR←error("XR←GetNextHandlee called with thread != NIL!"); } #undef XR←RegisterThreadStartProc void XR←RegisterThreadStartProc(startProc) XR←MesaProc startProc; { } /* * Per thread data access and set routines * Using a global variable rather than adding a field to the thread * data structure because perThread data in a single threaded world * might as well be perWorld data */ XR←Pointer t←perThreadData = 0; XR←Pointer XR←GetThreadProperty() { return t←perThreadData; } void XR←SetThreadProperty(p) XR←Pointer p; { t←perThreadData = p; }