/* * sThreads.c -- stubbed out PCR * * July 6, 1993 - mfp * XR_PauseAbortable fixed to set the return value as specified in Threads.h */ #include #include #include #include #include #include #include #include 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; }