/* * THREAD.C */ #include "defs.h" #include /* * Threaded call support, wraps threaded procedure call. * * Start running the threaded procedure in ntd's stack context but otd's real * context. Upon return we ensure that we are detached by calling * threadReturnSynchronous() (which puts us into ntd's context proper), and * then simply fall off the end, which puts ntd back into the FreeQueue. * * NOTE: td_RefStor is pre-initialized by threadCreate() (or left over from * prior thread use), including its held lock. */ void RUNERUNTIME(ThreadedCall) (void *args, void *res, void RUNEENTRYABI(*func) (void *, void *)); void RUNERUNTIME(ThreadedDetach) (void); static void startThreadedCall(void *data) { ThreadCall *tc; tc = data; tc->func(tc->args, tc->res); /* <--- CALL THREADED RUNE FUNCTION */ threadReturnSynchronous(); /* * This point is reached when the thread we had used (ntd) is ready to be * recycled. tc is invalid, otd could also be long gone, and * td_StartFunc/StartData have already been repurposed. */ } /* * Called from generated code at run-time, cothread placed on run-queue but * guaranteed not to run immediately. We then stop our current thread and * wait for the cothread to detach. */ void RUNERUNTIME(ThreadedCall) (void *args, void *res, void RUNEENTRYABI(*func) (void *, void *)) { ThreadCall *savetc; ThreadCall tc; runethr_t *td = getrgd()->CurThread; savetc = td->td_StartData; tc.args = args; tc.res = res; tc.func = func; threadCreateSynchronous(startThreadedCall, &tc); /* original parent (otd) returns here */ /* rgd invalid */ td->td_StartData = savetc; } void RUNERUNTIME(ThreadedDetach)(void) { threadDetachSynchronous(); #if 0 runethr_t *td = getrgd()->CurThread; ThreadCall *tc; tc = td->td_StartData; if (tc) #endif } void RUNERUNTIME(TSched)(int mode) { static int counter; switch(mode) { case SPECIAL_AUX_IMMEDIATE: threadSwitch(); break; case SPECIAL_AUX_NOPREEMPT: case SPECIAL_AUX_PREEMPT: break; default: /* * Normal mode, every so often XXX */ if (++counter > 5000) { counter = 0; threadSwitch(); } break; } }