LOCAL STATUS taskSwapMaskClear ( int tid, /* task to change swap-in mask */ int index, /* index of task swap routine in taskSwapTable */ BOOL in, /* swap routine called when task is switched in */ BOOL out /* swap routine called when task is switched out */ ) { WIND_TCB *pTcb = taskTcb (tid); USHORT ixBit = (1 << (15 - index)); if (pTcb == NULL) /* invalid task ID */ return (ERROR); if (((in) && !(pTcb->swapInMask & ixBit)) || ((out) && !(pTcb->swapOutMask & ixBit))) { errno = S_taskLib_TASK_SWAP_HOOK_CLEAR; return (ERROR); } if (in) pTcb->swapInMask &= ~ixBit; /* turn off swapInMask bit */ if (out) pTcb->swapOutMask &= ~ixBit; /* turn off swapOutMask bit */ return (OK); }
void sem1Task (long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { WIND_TCB *pTcb = taskTcb(taskIdSelf()); TEST_ASSERT(pTcb != NULL); TEST_ASSERT(semFlush(mutexid) == ERROR && errno == S_semLib_INVALID_OPERATION); TEST_ASSERT_OK(semFlush(bsemid)); TEST_MARK(); TEST_ASSERT_OK(semTake(mutexid,WAIT_FOREVER)); TEST_MARK(); TEST_ASSERT_OK(semGive(bsemid)); TEST_MARK(); TEST_ASSERT_OK(semGive(mutexid)); TEST_MARK(); /* Should not pass this mark */ }
STATUS taskPriorityGet( int taskId, unsigned *priority ) { STATUS status; TCB_ID tcbId; /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) { status = ERROR; } else { /* TASK_ID_VERIFY() already done by taskTcb() */ /* Store priority */ *priority = tcbId->priority; status = OK; } return status; }
void sem2Task (long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { WIND_TCB *pTcb = taskTcb(taskIdSelf()); ULONG date; int n; TEST_ASSERT(pTcb != NULL); TEST_ASSERT(taskNameToId("Test2") == (TASK_ID)pTcb); TEST_MARK(); TEST_ASSERT_OK(semTake(bsemid,WAIT_FOREVER)); TEST_MARK(); TEST_ASSERT_OK(semTake(bsemid,WAIT_FOREVER)); TEST_MARK(); TEST_ASSERT_OK(taskResume(a0)); TEST_MARK(); date = tickGet(); for (n = 0; n < 1000000; n++) { ULONG old_date = date; date = tickGet(); if (date != old_date) TEST_MARK(); } TEST_MARK(); /* Should not pass this mark */ }
/* * Return the name of a task */ const char * taskName(long tid) { OS_TCB *tcb = taskTcb(tid); if (tcb == NULL) return NULL; return tcb->name; }
int errnoGet(void) { OS_TCB *tcb = taskTcb(taskIdSelf()); if (tcb != NULL) { return tcb->errorStatus; } return 0; }
/* * Set some user data associated with the task */ STATUS taskSetUserData(long tid, unsigned long data) { OS_TCB *tcb = taskTcb(tid); if (tcb->magic != TASK_MAGIC) { errnoSet(S_portLib_INVALID_TASKID); return ERROR; } tcb->userData = data; return OK; }
STATUS errnoSet(int errorValue) { OS_TCB *tcb = taskTcb(taskIdSelf()); if (tcb != NULL && tcb->magic == TASK_MAGIC) { tcb->errorStatus = errorValue; return OK; } else { fprintf(stderr, "errnoSet: no TCB %ld\n", taskIdSelf()); return ERROR; } }
STATUS taskOptionsString ( int tid, /* task to get options string for */ char *pString /* where to return string of options */ ) { WIND_TCB *pTcb = taskTcb (tid); if (pTcb == NULL) return (ERROR); pString[0] = EOS; /* null terminate string */ if (pTcb->options & VX_SUPERVISOR_MODE) strcat (pString, "VX_SUPERVISOR_MODE "); if (pTcb->options & VX_UNBREAKABLE) strcat (pString, "VX_UNBREAKABLE "); if (pTcb->options & VX_DEALLOC_STACK) strcat (pString, "VX_DEALLOC_STACK "); if (pTcb->options & VX_FP_TASK) strcat (pString, "VX_FP_TASK "); if (pTcb->options & VX_DSP_TASK) strcat (pString, "VX_DSP_TASK "); #ifdef _WRS_ALTIVEC_SUPPORT if (pTcb->options & VX_ALTIVEC_TASK) strcat (pString, "VX_ALTIVEC_TASK "); #endif /* _WRS_ALTIVEC_SUPPORT */ if (pTcb->options & VX_STDIO) strcat (pString, "VX_STDIO "); if (pTcb->options & VX_ADA_DEBUG) strcat (pString, "VX_ADA_DEBUG "); if (pTcb->options & VX_FORTRAN) strcat (pString, "VX_FORTRAN "); if (pTcb->options & VX_PRIVATE_ENV) strcat (pString, "VX_PRIVATE_ENV "); if (pTcb->options & VX_NO_STACK_FILL) strcat (pString, "VX_NO_STACK_FILL "); return (OK); }
/* * Examine task options */ STATUS taskOptionsGet(long tid, int *pOptions) { OS_TCB *tcb = taskTcb(tid); if (tcb == NULL) return ERROR; if (tcb->magic != TASK_MAGIC) { errnoSet(S_portLib_INVALID_TASKID); return ERROR; } if (pOptions) *pOptions = tcb->options; return OK; }
STATUS taskSRSet ( int tid, /* task ID */ UINT eflags /* new EFLAGS */ ) { FAST WIND_TCB *pTcb = taskTcb (tid); if (pTcb == NULL) /* task non-existent */ return (ERROR); pTcb->regs.eflags = eflags; return (OK); }
STATUS taskStatusString ( int tid, /* task to get string for */ char *pString /* where to return string */ ) { WIND_TCB *pTcb = taskTcb (tid); if (pTcb == NULL) return (ERROR); switch (pTcb->status) { case WIND_READY: strcpy (pString, "READY"); break; case WIND_DELAY: strcpy (pString, "DELAY"); break; case WIND_DELAY | WIND_SUSPEND: strcpy (pString, "DELAY+S"); break; case WIND_PEND: strcpy (pString, "PEND"); break; case WIND_PEND | WIND_DELAY: strcpy (pString, "PEND+T"); break; case WIND_PEND | WIND_SUSPEND: strcpy (pString, "PEND+S"); break; case WIND_PEND | WIND_DELAY | WIND_SUSPEND: strcpy (pString, "PEND+S+T"); break; case WIND_SUSPEND: strcpy (pString, "SUSPEND"); break; case WIND_DEAD: strcpy (pString, "DEAD"); break; default: /* unanticipated combination */ sprintf (pString, "0x%02x", pTcb->status); return (ERROR); } if (pTcb->priority != pTcb->priNormal) strcat (pString, "+I"); /* task's priority inherited */ return (OK); }
/* * Change task options */ STATUS taskOptionsSet(long tid, int mask, int newOptions) { OS_TCB *tcb = taskTcb(tid); if (tcb == NULL) { errnoSet(S_portLib_INVALID_TASKID); return ERROR; } if (tcb->magic != TASK_MAGIC) { errnoSet(S_portLib_INVALID_TASKID); return ERROR; } tcb->options = (tcb->options & ~mask) | newOptions; return OK; }
void* taskStackAllot( int taskId, unsigned size ) { TCB_ID tcbId; char *pStackPrev; void *pNewMem; /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) { pNewMem = NULL; } else { /* TASK_ID_VERIFY() already done by taskTcb() */ /* Round up */ size = STACK_ROUND_UP(size); /* Check if size is ok */ if (size > (tcbId->pStackLimit - tcbId->pStackBase) * _STACK_DIR) { errnoSet(S_taskLib_STACK_OVERFLOW); pNewMem = NULL; } else { #if (_STACK_DIR == _STACK_GROWS_DOWN) pStackPrev = tcbId->pStackLimit; tcbId->pStackLimit += size; pNewMem = pStackPrev; #else /* _STACK_GROWS_UP */ tcbId->pStackLimit -= size; pNewMem = tcbId->pStackLimit; #endif /* _STACK_DIR */ } } return pNewMem; }
/* * Return the user data associated with the task */ unsigned long taskGetUserData(long tid) { OS_TCB *tcb = taskTcb(tid); if (tcb != NULL) { if (tcb->magic != TASK_MAGIC) { errnoSet(S_portLib_INVALID_TASKID); fprintf(stderr, "taskGetUserData: bad/unregisterd taskId %ld %lx\n", tid, (unsigned long)pthread_self()); return 0; } return tcb->userData; } else { fprintf(stderr, "taskLib: fatal error: taskGetUserData: tcb == NULL.\n"); abort(); } }
STATUS taskPrioritySet( int taskId, unsigned priority ) { STATUS status; TCB_ID tcbId; /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) { status = ERROR; } else { /* TASK_ID_VERIFY() already done by taskTcb() */ /* Check if in kernel mode */ if (kernelState == TRUE) { /* Add work to kernel */ workQAdd2((FUNCPTR) vmxPrioritySet, (ARG) tcbId, (ARG) priority); status = OK; } else { /* Enter kernel mode */ kernelState = TRUE; /* Set priority */ vmxPrioritySet(tcbId, priority); /* Exit trough kernel */ vmxExit(); status = OK; } } return status; }
STATUS taskIdVerify( int taskId ) { STATUS status; TCB_ID tcbId; /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) { status = ERROR; } else { /* TASK_ID_VERIFY() already done by taskTcb() */ status = OK; } return status; }
STATUS taskSuspend( int taskId ) { STATUS status; TCB_ID tcbId; /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) { status = ERROR; } else { /* TASK_ID_VERIFY() already done by taskTcb() */ /* Check if in kernel mode */ if (kernelState == TRUE) { /* Add to kernel queue */ workQAdd1((FUNCPTR) vmxSuspend, (ARG) tcbId); status = OK; } else { /* Enter kernel mode */ kernelState = TRUE; /* Suspend task */ vmxSuspend(tcbId); /* Exit trough kernel */ vmxExit(); status = OK; } } return status; }
STATUS taskInfoGet ( int tid, /* ID of task for which to get info */ TASK_DESC *pTaskDesc /* task descriptor to be filled in */ ) { int key; FAST char *pStackHigh; FAST TASK_DESC *pTd = pTaskDesc; WIND_TCB *pTcb = taskTcb (tid); if (pTcb == NULL) /* valid task ID? */ return (ERROR); /* gather the information */ #if CPU_FAMILY==I960 if (tid != taskIdSelf ()) /* showing our current sp is not possible */ taskRegsStackToTcb (pTcb); #endif /* CPU_FAMILY==I960 */ pTd->td_id = (int) pTcb; /* task ID */ pTd->td_name = pTcb->name; /* name of task */ pTd->td_priority = (int) pTcb->priority; /* priority */ pTd->td_status = pTcb->status; /* task status*/ pTd->td_options = pTcb->options; /* task option bits */ pTd->td_entry = pTcb->entry; /* entry of task */ pTd->td_sp = (char *)((int)pTcb->regs.spReg); /* saved stack ptr */ pTd->td_pStackLimit = pTcb->pStackLimit; /* limit of stack */ pTd->td_pStackBase = pTcb->pStackBase; /* bottom of stack */ pTd->td_pStackEnd = pTcb->pStackEnd; /* end of the stack */ #if (_STACK_DIR==_STACK_GROWS_DOWN) if (pTcb->options & VX_NO_STACK_FILL) pStackHigh = pTcb->pStackLimit; else for (pStackHigh = pTcb->pStackLimit; *(UINT8 *)pStackHigh == 0xee; pStackHigh ++) ; #else /* _STACK_GROWS_UP */ if (pTcb->options & VX_NO_STACK_FILL) pStackHigh = pTcb->pStackLimit - 1; else for (pStackHigh = pTcb->pStackLimit - 1; *(UINT8 *)pStackHigh == 0xee; pStackHigh --) ; #endif /* _STACK_GROWS_UP */ pTd->td_stackSize = (int)(pTcb->pStackLimit - pTcb->pStackBase) * _STACK_DIR; pTd->td_stackHigh = (int)(pStackHigh - pTcb->pStackBase) * _STACK_DIR; pTd->td_stackMargin = (int)(pTcb->pStackLimit - pStackHigh) * _STACK_DIR; pTd->td_stackCurrent= (int)(pTd->td_sp - pTcb->pStackBase) * _STACK_DIR; pTd->td_errorStatus = errnoOfTaskGet (tid); /* most recent error */ /* if task is delayed, get the time to fire out of the task's tick node */ if (pTcb->status & WIND_DELAY) pTd->td_delay = Q_KEY (&tickQHead, &pTcb->tickNode, 1); else pTd->td_delay = 0; /* not delayed */ /* copy the VxWorks events information */ key = intLock (); pTd->td_events = pTcb->events; intUnlock (key); return (OK); }
STATUS taskDestroy( int taskId, BOOL freeStack, unsigned timeout, BOOL forceDestroy ) { STATUS status; int i, level; TCB_ID tcbId; if (INT_RESTRICT() != OK) { errnoSet (S_intLib_NOT_ISR_CALLABLE); return ERROR; } /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) return ERROR; /* If task self destruct and excption lib installed */ if (tcbId == taskIdCurrent) { /* Wait for safe to destroy */ while (tcbId->safeCount > 0) taskUnsafe(); /* Kill it */ status = excJobAdd( (VOIDFUNCPTR) taskDestroy, (ARG) tcbId, (ARG) freeStack, (ARG) WAIT_NONE, (ARG) FALSE, (ARG) 0, (ARG) 0 ); /* Block here and suspend */ while(status == OK) taskSuspend(0); } /* End if task self destruct and exception lib installed */ taskDestroyLoop: /* Lock interrupts */ INT_LOCK(level); /* Check id */ if (TASK_ID_VERIFY(tcbId) != OK) { /* errno set by taskIdVerify() */ /* Unlock interrupts */ INT_UNLOCK(level); return ERROR; } /* Mask all signals */ if (tcbId->pSignalInfo != NULL) tcbId->pSignalInfo->sigt_blocked = 0xffffffff; /* Block here for safe and running locked tasks */ while ( (tcbId->safeCount > 0) || ( (tcbId->status == TASK_READY) && (tcbId->lockCount > 0) ) ) { /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Check if force deletion, or suicide */ if (forceDestroy || (tcbId == taskIdCurrent)) { /* Remove protections */ tcbId->safeCount = 0; tcbId->lockCount = 0; /* Check if flush of safety queue is needed */ if (Q_FIRST(&tcbId->safetyQ) != NULL) vmxPendQFlush(&tcbId->safetyQ); /* Exit trough kernel */ vmxExit(); } else { /* Not forced deletion or suicide */ /* Put task on safe queue */ if (vmxPendQPut(&tcbId->safetyQ, timeout) != OK) { /* Exit trough kernel */ vmxExit(); errnoSet (S_taskLib_INVALID_TIMEOUT); return ERROR; } /* Exit trough kernel */ status = vmxExit(); /* Check for restart */ if (status == SIG_RESTART) { timeout = (sigTimeoutRecalc)(timeout); goto taskDestroyLoop; } /* Check if unsuccessful */ if (status == ERROR) { /* timer should have set errno to S_objLib_TIMEOUT */ return ERROR; } } /* End else forced or suicide */ /* Lock interrupts */ INT_LOCK(level); /* Now verify class id again */ if (TASK_ID_VERIFY(tcbId) != OK) { /* errno set by taskIdVerify() */ /* Unlock interrupts */ INT_UNLOCK(level); return ERROR; } } /* End while blocked by safety */ /* Now only one cadidate is selected for deletion */ /* Make myself safe */ taskSafe(); /* Protet deletion cadidate */ tcbId->safeCount++; /* Check if not suicide */ if (tcbId != taskIdCurrent) { /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Suspend victim */ vmxSuspend(tcbId); /* Exit trough kernel */ vmxExit(); } else { /* Unlock interrupts */ INT_UNLOCK(level); } /* Run deletion hooks */ for (i = 0; i < MAX_TASK_DELETE_HOOKS; i++) if (taskDeleteHooks[i] != NULL) (*taskDeleteHooks[i])(tcbId); /* Lock task */ taskLock(); /* If dealloc and options dealloc stack */ if ( freeStack && (tcbId->options & TASK_OPTIONS_DEALLOC_STACK) ) { #if (_STACK_DIR == _STACK_GROWS_DOWN) objFree(taskClassId, tcbId->pStackEnd); #else /* _STACK_GROWS_UP */ objFree(taskClassId, tbcId - TASK_EXTRA_BYTES); #endif /* _STACK_DIR */ } /* Lock interrupts */ INT_LOCK(level); /* Invalidate id */ objCoreTerminate(&tcbId->objCore); /* Enter kernel mode */ kernelState = TRUE; /* Unlock interrupts */ INT_UNLOCK(level); /* Delete task */ status = vmxDelete(tcbId); /* Check if safe quque needs to be flushed */ if (Q_FIRST(&tcbId->safetyQ) != NULL) vmxPendQFlush(&tcbId->safetyQ); /* Exit trough kernel */ vmxExit(); /* Unprotect */ taskUnlock(); taskUnsafe(); return OK; }
void rootTask (long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7, long a8, long a9) { WIND_TCB *pTcb; TEST_START(0); pTcb = taskTcb(taskIdSelf()); TEST_ASSERT(pTcb != NULL); bsemid = semBCreate(0xffffffff,0); TEST_ASSERT(bsemid == 0 && errno == S_semLib_INVALID_QUEUE_TYPE); bsemid = semBCreate(SEM_Q_PRIORITY,0); TEST_ASSERT(bsemid != 0); mutexid = semMCreate(0xffffffff); TEST_ASSERT(mutexid == 0 && errno == S_semLib_INVALID_QUEUE_TYPE); mutexid = semMCreate(SEM_Q_PRIORITY|SEM_DELETE_SAFE|SEM_INVERSION_SAFE); TEST_ASSERT(mutexid != 0); taskSpawn("Test1", 20, /* low-pri */ 0, 32768, sem1Task, taskIdSelf(),0,0,0,0,0,0,0,0,0); taskSpawn("Test2", 10, /* intermediate-pri */ 0, 32768, sem2Task, taskIdSelf(),0,0,0,0,0,0,0,0,0); /* This runs at high-pri */ TEST_MARK(); TEST_ASSERT_OK(semTake(bsemid,WAIT_FOREVER)); TEST_MARK(); TEST_ASSERT_OK(taskSuspend(0)); TEST_MARK(); TEST_ASSERT_OK(semTake(mutexid,WAIT_FOREVER)); TEST_MARK(); TEST_ASSERT_OK(semGive(mutexid)); TEST_MARK(); TEST_ASSERT(taskIsReady(taskNameToId("Test2"))); TEST_ASSERT(!taskIsSuspended(taskNameToId("Test2"))); TEST_ASSERT_OK(taskDelay(1)); TEST_MARK(); TEST_CHECK_SEQUENCE(SEQ("root",1), SEQ("Test2",1), SEQ("root",1), SEQ("Test2",1), SEQ("Test1",2), SEQ("Test2",1), SEQ("root",1), SEQ("Test1",1), SEQ("root",2), SEQ("Test2",1), SEQ("root",1), END_SEQ); TEST_FINISH(); }
STATUS taskRestart( int taskId ) { TCB_ID tcbId; char *name, *rename; int len; unsigned priority; int options; char *pStackBase; unsigned stackSize; FUNCPTR entry; ARG args[MAX_TASK_ARGS]; STATUS status; if (INT_RESTRICT() != OK) { errnoSet(S_intLib_NOT_ISR_CALLABLE); return ERROR; } /* If self restart */ if ( (taskId == 0) || (taskId == (int) taskIdCurrent) ) { /* Task must be unsafe */ while (taskIdCurrent->safeCount > 0) taskSafe(); /* Spawn a task that will restart this task */ taskSpawn(restartTaskName, restartTaskPriority, restartTaskOptions, restartTaskStackSize, taskRestart, (ARG) taskIdCurrent, (ARG) 0, (ARG) 0, (ARG) 0, (ARG) 0, (ARG) 0, (ARG) 0, (ARG) 0, (ARG) 0, (ARG) 0); /* Wait for restart */ while (1) taskSuspend(0); } /* End if self restart */ /* Get task context */ tcbId = taskTcb(taskId); if (tcbId == NULL) return ERROR; /* TASK_ID_VERIFY() already done by taskTcb() */ /* Copy task data */ priority = tcbId->priority; options = tcbId->options; entry = tcbId->entry; pStackBase = tcbId->pStackBase; stackSize = (tcbId->pStackEnd - tcbId->pStackBase) * _STACK_DIR; taskArgGet(tcbId, pStackBase, args); /* Copy name if needed */ name = tcbId->name; rename = NULL; if (name != NULL) { len = strlen(name) + 1; rename = malloc(len); if (rename != NULL) strcpy(rename, name); name = rename; } /* Prevent deletion */ taskSafe(); if (taskTerminate((int) tcbId) != OK) { taskUnsafe(); /* errno set by taskTerminate() */ return ERROR; } /* Initialize task with same data */ status = taskInit(tcbId, name, priority, options, pStackBase, stackSize, entry, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); if (status != OK) { /* errno set by taskInit() */ return ERROR; } /* And start it */ status = taskActivate((int) tcbId); if (status != OK) { /* errno set by taskActivate() */ return ERROR; } /* Make me mortal */ taskUnsafe(); /* Free rename buffer if needed */ if (rename != NULL) free(rename); return OK; }
/* * Executed by the child process */ static void cmdTaskEntry(char *program, MprCmdTaskFn entry, int cmdArg) { MprCmd *cmd; MprCmdFile *files; WIND_TCB *tcb; char **ep, *dir; int inFd, outFd, errFd, id, rc; cmd = (MprCmd*) cmdArg; /* * Open standard I/O files (in/out are from the server's perspective) */ files = cmd->files; inFd = open(files[MPR_CMD_STDIN].name, O_RDONLY, 0666); outFd = open(files[MPR_CMD_STDOUT].name, O_WRONLY, 0666); errFd = open(files[MPR_CMD_STDERR].name, O_WRONLY, 0666); if (inFd < 0 || outFd < 0 || errFd < 0) { exit(255); } id = taskIdSelf(); ioTaskStdSet(id, 0, inFd); ioTaskStdSet(id, 1, outFd); ioTaskStdSet(id, 2, errFd); /* * Now that we have opened the stdin and stdout, wakeup our parent. */ semGive(cmd->startCond); /* * Create the environment */ if (envPrivateCreate(id, -1) < 0) { exit(254); } for (ep = cmd->env; ep && *ep; ep++) { putenv(*ep); } /* * Set current directory if required */ if (cmd->dir) { rc = chdir(cmd->dir); } else { dir = mprGetPathDir(cmd, cmd->program); rc = chdir(dir); mprFree(dir); } if (rc < 0) { mprLog(cmd, 0, "cmd: Can't change directory to %s", cmd->dir); exit(255); } /* * Call the user's entry point */ (entry)(cmd->argc, cmd->argv, cmd->env); tcb = taskTcb(id); cmd->status = tcb->exitCode; /* * Cleanup */ envPrivateDestroy(id); close(inFd); close(outFd); close(errFd); semGive(cmd->exitCond); }
/* Executed by the child process */ static void cmdTaskEntry(char *program, MprCmdTaskFn entry, int cmdArg) { MprCmd *cmd; MprCmdFile *files; WIND_TCB *tcb; char *item; int inFd, outFd, errFd, id, next; cmd = (MprCmd*) cmdArg; /* Open standard I/O files (in/out are from the server's perspective) */ files = cmd->files; inFd = open(files[MPR_CMD_STDIN].name, O_RDONLY, 0666); outFd = open(files[MPR_CMD_STDOUT].name, O_WRONLY, 0666); errFd = open(files[MPR_CMD_STDERR].name, O_WRONLY, 0666); if (inFd < 0 || outFd < 0 || errFd < 0) { exit(255); } id = taskIdSelf(); ioTaskStdSet(id, 0, inFd); ioTaskStdSet(id, 1, outFd); ioTaskStdSet(id, 2, errFd); /* Now that we have opened the stdin and stdout, wakeup our parent. */ semGive(cmd->startCond); /* Create the environment */ if (envPrivateCreate(id, -1) < 0) { exit(254); } for (ITERATE_ITEMS(cmd->env, item, next)) { putenv(item); } #if !VXWORKS { char *dir; int rc; /* Set current directory if required WARNING: Setting working directory on VxWorks is global */ if (cmd->dir) { rc = chdir(cmd->dir); } else { dir = mprGetPathDir(cmd->program); rc = chdir(dir); } if (rc < 0) { mprLog("error mpr cmd", 0, "Cannot change directory to %s", cmd->dir); exit(255); } } #endif /* Call the user's entry point */ (entry)(cmd->argc, (char**) cmd->argv, (char**) cmd->env); tcb = taskTcb(id); cmd->status = tcb->exitCode; /* Cleanup */ envPrivateDestroy(id); close(inFd); close(outFd); close(errFd); semGive(cmd->exitCond); }
STATUS taskShow ( int tid, /* task ID */ int level /* 0 = summary, 1 = details, 2 = all tasks */ ) { FAST int nTasks; /* number of task */ FAST int ix; /* index */ TASK_DESC td; /* task descriptor for task info */ WIND_TCB * pTcb; /* pointer to tasks tcb */ int idList[MAX_DSP_TASKS]; /* list of active IDs */ char optionsString[256]; /* task options string */ tid = taskIdDefault (tid); /* get default task */ switch (level) { case 0 : /* summarize a task */ { if (taskInfoGet (tid, &td) != OK) { printErr ("Task not found.\n"); return (ERROR); } printf (infoHdr); taskSummary (&td); break; } case 1 : /* get task detail */ { if (taskInfoGet (tid, &td) != OK) { printErr ("Task not found.\n"); return (ERROR); } taskOptionsString (tid, optionsString); /* get options string */ /* Print the summary as in all_task_info, then all the regs. */ printf (infoHdr); /* banner */ taskSummary (&td); printf ("\nstack: base 0x%-6x end 0x%-6x size %-5d ", (int)td.td_pStackBase, (int)td.td_pStackEnd, td.td_stackSize); if (td.td_options & VX_NO_STACK_FILL) printf ("high %5s margin %5s\n", "???", "???"); else printf ("high %-5d margin %-5d\n", td.td_stackHigh, td.td_stackMargin); printf ("\noptions: 0x%x\n%s\n", td.td_options, optionsString); /* display VxWorks events information */ eventTaskShow (&td.td_events); if (tid != taskIdSelf ()) /* no self exam */ { taskRegsShow (tid); if (_func_fppTaskRegsShow != NULL) /* fp regs if attached*/ (* _func_fppTaskRegsShow) (tid); if (_func_dspTaskRegsShow != NULL) /* dsp regs if attached*/ (* _func_dspTaskRegsShow) (tid); #ifdef _WRS_ALTIVEC_SUPPORT if (_func_altivecTaskRegsShow != NULL) /* altivec regs if attached*/ (* _func_altivecTaskRegsShow) (tid); #endif /* _WRS_ALTIVEC_SUPPORT */ #if (CPU_FAMILY==I80X86) if (_func_sseTaskRegsShow != NULL) /* SIMD regs if attached */ (* _func_sseTaskRegsShow) (tid); #endif /* (CPU_FAMILY==I80X86) */ } /* print exception info if any */ if ((_func_excInfoShow != NULL) && ((pTcb = taskTcb (tid)) != NULL)) (* _func_excInfoShow) (&pTcb->excInfo, FALSE); break; } case 2 : /* summarize all tasks */ default : { printf (infoHdr); nTasks = taskIdListGet (idList, NELEMENTS (idList)); taskIdListSort (idList, nTasks); for (ix = 0; ix < nTasks; ++ix) { if (taskInfoGet (idList [ix], &td) == OK) taskSummary (&td); } break; } } return (OK); }