📄 tasklib.c
字号:
pTcb->pStackBase = pStackBase; /* initialize stack base */ pTcb->pStackLimit = pStackBase + stackSize*_STACK_DIR; pTcb->pStackEnd = pTcb->pStackLimit; if (!(options & VX_NO_STACK_FILL)) /* fill w/ 0xee for checkStack*/#if (_STACK_DIR == _STACK_GROWS_DOWN) bfill (pTcb->pStackLimit, stackSize, 0xee);#else /* (_STACK_DIR == _STACK_GROWS_UP) */ bfill (pTcb->pStackBase, stackSize, 0xee);#endif /* (_STACK_DIR == _STACK_GROWS_UP) */#if (CPU_FAMILY == AM29XXX) taskRegsInit (pTcb, pStackBase, stackSize); /* initialize register set */#else /* (CPU_FAMILY == AM29XXX) */ taskRegsInit (pTcb, pStackBase); /* initialize register set */#endif /* (CPU_FAMILY == AM29XXX) */ pTcb->errorStatus = OK; /* errorStatus */ pTcb->exitCode = OK; /* field for exit () */ pTcb->pSignalInfo = NULL; /* ptr to signal context */ pTcb->pSelWakeupNode= NULL; /* not in select initially */ pTcb->ppEnviron = NULL; /* global environment vars */ pTcb->taskTicks = 0; /* profiling for spyLib */ pTcb->taskIncTicks = 0; /* profiling for spyLib */#if CPU_FAMILY!=I960 pTcb->excInfo.valid = 0; /* exception info is invalid */#else /* CPU_FAMILY == I960 */ pTcb->excInfo.eiType = 0;#endif /* CPU_FAMILY!=I960 */ pTcb->pTaskVar = NULL; /* list of task variables */ pTcb->pRPCModList = NULL; /* rpc module statics context */ pTcb->pFpContext = NULL; /* floating point context */ for (ix = 0; ix < 3; ++ix) { pTcb->taskStd[ix] = ix; /* stdin/stdout/stderr fds */ pTcb->taskStdFp[ix] = NULL; /* stdin/stdout/stderr fps */ } pTcb->pSmObjTcb = NULL; /* no shared TCB for now */ pTcb->windxLock = NULL; pTcb->pComLocal = NULL; pTcb->pExcRegSet = NULL; pTcb->reserved1 = NULL; pTcb->reserved2 = NULL; pTcb->spare1 = NULL; pTcb->spare2 = NULL; pTcb->spare3 = NULL; pTcb->spare4 = NULL; pTcb->wdbInfo.wdbState = 0; pTcb->wdbInfo.bpAddr = 0; pTcb->wdbExitHook = NULL; taskArgsSet (pTcb, pStackBase, pArgs); /* initialize task arguments */#ifdef WV_INSTRUMENTATION /* windview instrumentation */ /* windview - level 1 event logging * The objCore has not been initialised yet so this must be done * by hand. */ EVT_OBJ_TASKSPAWN (EVENT_TASKSPAWN, (int) pTcb, priority, stackSize, (int) entryPt, options); /* windview - The parser must be able to link a name with a task id. */ EVT_CTX_TASKINFO (EVENT_TASKNAME, WIND_SUSPEND, pTcb->priority, pTcb->lockCnt, (int) pTcb, name);#endif kernelState = TRUE; /* KERNEL ENTER */ windSpawn (pTcb); /* spawn the task */#ifdef WV_INSTRUMENTATION /* windview - connect the instrumented class for level 1 event logging */ if (wvObjIsEnabled) objCoreInit (&pTcb->objCore, taskInstClassId); else#endif objCoreInit (&pTcb->objCore, taskClassId); /* validate task ID */ windExit (); /* KERNEL EXIT */ if (name != NULL) /* copy name if not nameless */ { taskNameLen = (unsigned) (strlen (name) + 1); taskName = (char *) taskStackAllot ((int) pTcb, taskNameLen); strcpy (taskName, name); /* copy the name onto stack */ } pTcb->name = taskName; /* name of this task */ for (ix = 0; ix < VX_MAX_TASK_CREATE_RTNS; ++ix) { if (taskCreateTable[ix] != NULL) (*taskCreateTable[ix]) (pTcb); } return (OK); /* return task ID */ }/********************************************************************************* taskActivate - activate a task that has been initialized** This routine activates tasks created by taskInit(). Without activation, a* task is ineligible for CPU allocation by the scheduler.* * The <tid> (task ID) argument is simply the address of the WIND_TCB* for the task (the taskInit() <pTcb> argument), cast to an integer:* .CS* tid = (int) pTcb;* .CE** The taskSpawn() routine is built from taskActivate() and taskInit().* Tasks created by taskSpawn() do not require explicit task activation.** RETURNS: OK, or ERROR if the task cannot be activated.** SEE ALSO: taskInit()*/STATUS taskActivate ( int tid /* task ID of task to activate */ ) { return (taskResume (tid)); /* taskActivate == taskResume */ }/********************************************************************************* exit - exit a task (ANSI)** This routine is called by a task to cease to exist as a task. It is* called implicitly when the "main" routine of a spawned task is exited.* The <code> parameter will be stored in the WIND_TCB for* possible use by the delete hooks, or post-mortem debugging.** ERRNO: N/A** SEE ALSO: taskDelete(),* .I "American National Standard for Information Systems -"* .I "Programming Language - C, ANSI X3.159-1989: Input/Output (stdlib.h),"* .pG "Basic OS"*/void exit ( int code /* code stored in TCB for delete hooks */ ) { taskIdCurrent->exitCode = code; /* store the exit code */ taskLock (); /* LOCK PREEMPTION */ taskIdCurrent->options |= VX_UNBREAKABLE; /* mark as unbreakable */ if (taskBpHook != NULL) /* call the debugger hook */ (* taskBpHook) (taskIdCurrent); /* to remove all breakpoints */ taskUnlock (); /* UNLOCK PREEMPTION */ taskDestroy (0, TRUE, WAIT_FOREVER, FALSE); /* self destruct */ }/********************************************************************************* taskDelete - delete a task** This routine causes a specified task to cease to exist and deallocates the* stack and WIND_TCB memory resources. Upon deletion, all routines specified* by taskDeleteHookAdd() will be called in the context of the deleting task.* This routine is the companion routine to taskSpawn().** RETURNS: OK, or ERROR if the task cannot be deleted.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: excLib, taskDeleteHookAdd(), taskSpawn(),* .pG "Basic OS"*/STATUS taskDelete ( int tid /* task ID of task to delete */ ) { return (taskDestroy (tid, TRUE, WAIT_FOREVER, FALSE)); }/********************************************************************************* taskDeleteForce - delete a task without restriction** This routine deletes a task even if the task is protected from deletion. * It is similar to taskDelete(). Upon deletion, all routines* specified by taskDeleteHookAdd() will be called in the context of the* deleting task.** CAVEATS* This routine is intended as a debugging aid, and is generally inappropriate* for applications. Disregarding a task's deletion protection could leave the* the system in an unstable state or lead to system deadlock.** The system does not protect against simultaneous taskDeleteForce() calls.* Such a situation could leave the system in an unstable state.** RETURNS: OK, or ERROR if the task cannot be deleted.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED,* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: taskDeleteHookAdd(), taskDelete()*/STATUS taskDeleteForce ( int tid /* task ID of task to delete */ ) { return (taskDestroy (tid, TRUE, WAIT_FOREVER, TRUE)); }/********************************************************************************* taskTerminate - terminate a task** This routine causes a task to cease to exist but does not deallocate the* stack or WIND_TCB memory. During termination, all routines specified by* taskDeleteHookAdd() will be called in the context of the deleting task.* This routine serves as the companion routine to taskInit(). To delete a* task created by taskSpawn(), see taskDelete().** If a task attempts to terminate itself, the termination and the delete hooks* are performed in the context of the exception task.** RETURNS: OK, or ERROR if task cannot be terminated.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED,* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: excLib, taskDeleteHookAdd(), taskDelete(),* .pG "Basic OS"** NOMANUAL*/STATUS taskTerminate ( int tid /* task ID of task to delete */ ) { return (taskDestroy (tid, FALSE, WAIT_FOREVER, FALSE)); }/********************************************************************************* taskDestroy - destroy a task** This routine causes the specified task to cease to exist and, if successful,* optionally frees the memory associated with the task's stack and* WIND_TCB. This call forms the foundation to the routines taskDelete() and* taskTerminate(). Upon destruction, all routines specified by* taskDeleteHookAdd() will be called in the context of the destroying task.** If a task attempts to destroy itself, the destruction and the delete hooks* are performed in the context of the exception task.** RETURNS: OK, or ERROR if task cannot be destroyed.** ERRNO: S_intLib_NOT_ISR_CALLABLE, S_objLib_OBJ_DELETED,* S_objLib_OBJ_UNAVAILABLE, S_objLib_OBJ_ID_ERROR** SEE ALSO: excLib, taskDeleteHookAdd(), taskTerminate(), taskDelete()** NOMANUAL*/STATUS taskDestroy ( int tid, /* task ID of task to delete */ BOOL dealloc, /* deallocate associated memory */ int timeout, /* time willing to wait */ BOOL forceDestroy /* force deletion if protected */ ) { FAST int ix; /* delete hook index */ FAST WIND_TCB *pTcb; /* convenient pointer to WIND_TCB */ FAST int lock; /* to lock interrupts */ int status; /* windDelete return status */ if (INT_RESTRICT () != OK) /* no ISR use */ return (ERROR); if (tid == 0) pTcb = taskIdCurrent; /* suicide */ else pTcb = (WIND_TCB *) tid; /* convenient pointer */#ifdef WV_INSTRUMENTATION /* windview - level 1 event logging */ EVT_OBJ_2 (TASK, pTcb, taskClassId, EVENT_TASKDESTROY, pTcb, pTcb->safeCnt);#endif if ((pTcb == taskIdCurrent) && (_func_excJobAdd != NULL)) { /* If exception task is available, delete task from its context. * While suicides are supported without an exception task, it seems * safer to utilize another context for deletion. */ while (pTcb->safeCnt > 0) /* make task unsafe */ TASK_UNSAFE (); _func_excJobAdd (taskDestroy, (int)pTcb, dealloc, NO_WAIT, FALSE); FOREVER taskSuspend (0); /* wait to die */ }again: lock = intLock (); /* LOCK INTERRTUPTS */ if (TASK_ID_VERIFY (pTcb) != OK) /* valid task ID? */ { intUnlock (lock); /* UNLOCK INTERRUPTS */ return (ERROR); } /* * Mask all signals of pTcb (may be suicide) * This is the same as calling sigfillset(&pTcb->pSignalInfo->sigt_blocked) * without the call to sigLib */ if (pTcb->pSignalInfo != NULL) pTcb->pSignalInfo->sigt_blocked = 0xffffffff; while ((pTcb->safeCnt > 0) || ((pTcb->status == WIND_READY) && (pTcb->lockCnt > 0))) { kernelState = TRUE; /* KERNEL ENTER */ intUnlock (lock); /* UNLOCK INTERRUPTS */ if ((forceDestroy) || (pTcb == taskIdCurrent)) { pTcb->safeCnt = 0; /* unprotect */ pTcb->lockCnt = 0; /* unlock */ if (Q_FIRST (&pTcb->safetyQHead) != NULL) /* flush safe queue */ {#ifdef WV_INSTRUMENTATION /* windview - level 2 event logging */ EVT_TASK_1 (EVENT_OBJ_TASK, pTcb);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -