STATUS virtualStackNumTaskIdSet ( int vsNum ) { /* * If we this task does not have the task variable then * create it as part of this task. */ if (taskVarGet(0, (int *) &myStackNum) == ERROR) { if (errnoGet () == S_taskLib_TASK_VAR_NOT_FOUND) errnoSet (0); /* Resets the error caused by taskVarGet */ taskVarAdd (0, (int *) &myStackNum); } if (vsNum > VSID_MAX) return (ERROR); if (vsTbl[vsNum] == NULL) return (ERROR); myStackNum = vsNum; return (OK); }
volatile int *__erl_errno_place(void) { /* This check is somewhat insufficient, double task var entries will occur if __erl_errno is actually -1, which on the other hand is an invalid error code. */ if (taskVarGet(taskIdSelf(), &__erl_errno) == ERROR) { taskVarAdd(taskIdSelf(), &__erl_errno); } return &__erl_errno; }
STATUS virtualStackIdCheck ( ) { if (taskVarGet(0, (int *)&myStackNum) == ERROR) { taskVarAdd(0, (int *)&myStackNum); myStackNum = VS_MGMT_STACK; } return (OK); }
/* N.B.!! We do *not* execute in the context of the dying task here, but rather that of tExcTask - we do get a pointer to the task's TCB though - this pointer is in fact also the task's ID. */ static void save_reclaim(WIND_TCB *tcbp) { int i, var, oldfd; struct task_data *tdp; struct mall_data *mdp, *mdnextp; if ((var = taskVarGet((int)tcbp, (int *)&task_data)) != ERROR && var != 0) { tdp = (struct task_data *)var; if (tdp->version == (FUNCPTR)save_reclaim) { /* Only handle our own */ #ifdef DEBUG fdprintf(2, "Reclaiming for task id 0x%x:\nFiles: ", (int)tcbp); #endif /* Ugh! VxWorks doesn't even flush stdout/err - we need to get at those (which are task-private of course, i.e. we can't just do fflush(stdout) here) - we could be really pedantic and try to redefine stdout/err (which "are" function calls) too, snarfing the values when they are used - but besides the overhead this is problematic since they are actually #defines already... We'll peek in the TCB instead (no documentation of course). And of course, we must also meddle with the *file descriptor* indirections, or we'll just flush out on tExcTask's descriptors... */ for (i = 1; i <= 2; i++) { if (tcbp->taskStdFp[i] != NULL) { #ifdef DEBUG fdprintf(2, "fflush(%s) ", i == 1 ? "stdout" : "stderr"); #endif oldfd = ioTaskStdGet(0, i); ioTaskStdSet(0, i, tcbp->taskStd[i]); fflush(tcbp->taskStdFp[i]); ioTaskStdSet(0, i, oldfd); } } for (i = 3; i < tdp->max_files; i++) { if (FD_ISSET(i, &tdp->open_fds)) { #ifdef DEBUG fdprintf(2, "close(%d) ", i); #endif (void) close(i); } if (tdp->open_fps[i] != NULL) { #ifdef DEBUG fdprintf(2, "fclose(%0x%x) ", (int)tdp->open_fps[i]); #endif (void) fclose(tdp->open_fps[i]); } } i = 0; mdp = tdp->mall_data; while (mdp != NULL) { mdnextp = mdp->next; if(reclaim_free_function != NULL) (*reclaim_free_function)(mdp->self); else free(mdp->self); i++; mdp = mdnextp; } #ifdef DEBUG fdprintf(2, "\nFreeing memory: total %d mallocs\n", i); #endif if (tdp->delete_hook != NULL) { #ifdef DEBUG fdprintf(2, "Calling delete hook at 0x%08x\n", tdp->delete_hook); #endif (*tdp->delete_hook)(tdp->hook_data); #ifdef DEBUG fdprintf(2, "Called delete hook at 0x%08x\n", tdp->delete_hook); #endif } #ifdef DEBUG fdprintf(2, "Freeing own mem at 0x%08x\n", tdp); #endif (void) free((char *)tdp); #ifdef DEBUG fdprintf(2, "Freed own mem at 0x%08x, done (0x%08x)\n**********\n", tdp, taskIdSelf()); checkStack(0); #endif } } #ifdef DEBUG else fdprintf(2, "No task data found for id 0x%x, var = %d\n", (int)tcbp, var); #endif }