?? ss_task.c
字號:
RETVALUE(RFAILED);
}
/* initialize the system task entry lock */
if (SInitLock(&sTsk->lock, SS_STSKENTRY_LOCK) != ROK)
{
ssDestroyDmndQ(&sTsk->dQ);
SUnlock(&osCp.sTskTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS486, (ErrVal) ret,
"Could not initialize system task entry lock");
#endif
RETVALUE(RFAILED);
}
/* we ask the implementation to start this system task */
ret = ssdCreateSTsk(sTsk);
if (ret != ROK)
{
/* failed, clean up */
SDestroyLock(&sTsk->lock);
ssDestroyDmndQ(&sTsk->dQ);
sTsk->tskPrior = 0;
SUnlock(&osCp.sTskTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS487, (ErrVal) ret,
"Could not create system task");
#endif
RETVALUE(RFAILED);
}
/* success, update the table */
*tskId = osCp.nxtSTskEntry;
sTsk->tskId = osCp.nxtSTskEntry;
sTsk->used = TRUE;
sTsk->termPend = FALSE;
osCp.nxtSTskEntry = sTsk->nxt;
osCp.numSTsks++;
/* unlock the system task table */
SUnlock(&osCp.sTskTblLock);
RETVALUE(ROK);
} /* SCreateSTsk */
/*
*
* Fun: Destroy system task
*
* Desc: This function is used to destroy a system task. The
* entry is located in the system task table and the
* implementation-specific function is called.
*
* Ret: ROK - ok
* RFAILED - failed, general (optional)
*
* Notes:
*
* File: ss_task.c
*
*/
#ifdef ANSI
PUBLIC S16 SDestroySTsk
(
SSTskId tskId /* system task to be destroyed */
)
#else
PUBLIC S16 SDestroySTsk(tskId)
SSTskId tskId; /* system task to be destroyed */
#endif
{
S16 ret;
S16 i;
SsIdx idx;
SsSTskEntry *sTsk;
TRC1(SDestroySTsk);
#if (ERRCLASS & ERRCLS_INT_PAR)
/* validate the system task ID */
if (tskId >= SS_MAX_STSKS)
{
SSLOGERROR(ERRCLS_INT_PAR, ESS488, (ErrVal) tskId, "Invalid task ID");
RETVALUE(RFAILED);
}
#endif
/* lock the system task table */
ret = SLock(&osCp.sTskTblLock);
if (ret != ROK)
{
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS489, (ErrVal) ret,
"Could not lock system task table");
#endif
RETVALUE(RFAILED);
}
idx = (SsIdx) tskId;
sTsk = &osCp.sTskTbl[idx];
#if (ERRCLASS & ERRCLS_INT_PAR)
/*
* check to see this system task exists and it is not already scheduled
* for termination
*/
if (sTsk->used != TRUE)
{
SUnlock(&osCp.sTskTblLock);
SSLOGERROR(ERRCLS_INT_PAR, ESS490, (ErrVal) idx,
"Invalid system task ID");
RETVALUE(RFAILED);
} else if (sTsk->termPend != FALSE)
{
SUnlock(&osCp.sTskTblLock);
SSLOGERROR(ERRCLS_INT_PAR, ESS491, (ErrVal) idx,
"Invalid system task ID");
RETVALUE(RFAILED);
}
#endif
/* lock this system task entry */
if (!SS_CHECK_CUR_STSK(sTsk))
{
ret = SLock(&sTsk->lock);
if (ret != ROK)
{
SUnlock(&osCp.sTskTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS492, (ErrVal) ret,
"Could not lock system task entry");
#endif
RETVALUE(RFAILED);
}
}
/* lock the TAPA task table */
SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
if (ret != ROK)
{
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS493, ERRZERO,
"Could not lock TAPA task table");
#endif
RETVALUE(RFAILED);
}
/* If this system task entry has any TAPA tasks attached,
* we have to detach them
*/
if (sTsk->numTTsks)
{
/* detach all TAPA tasks that are attached here */
for (i = 0; i < SS_MAX_TTSKS; i++)
{
if (sTsk->tTsks[i] == SS_INVALID_IDX)
continue;
osCp.tTskTbl[sTsk->tTsks[i]].sTsk = NULLP;
sTsk->tTsks[i] = SS_INVALID_IDX;
sTsk->numTTsks--;
}
}
/* set the termination pending flag to TRUE */
sTsk->termPend = TRUE;
/* unlock everything */
SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
/* We call this after unlocking because it is possible that the
* caller is this very system task and we need to take care of
* that. The actual mechanism of notifying the thread that it
* has to die, or actually killing the thread is left to the
* implementation.
*/
ret = ssdDestroySTsk(sTsk);
if (ret != ROK)
{
/* Here, we're a little messed up. We've pretty much made this
* system task unusable, but now, its not going to die. So..??
*/
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS494, (ErrVal) ret,
"Could not destroy system task");
#endif
RETVALUE(RFAILED);
}
RETVALUE(ROK);
} /* SDestroySTsk */
/*
*
* Fun: Attach TAPA task
*
* Desc: This function is used to attach a TAPA task to a
* system task. The system task will begin to execute
* the TAPA task.
*
* Ret: ROK - ok
* RFAILED - failed, general (optional)
* ROUTRES - failed, out of resources (optional)
*
* Notes:
*
* File: ss_task.c
*
*/
#ifdef ANSI
PUBLIC S16 SAttachTTsk
(
Ent ent, /* entity ID of the task */
Inst inst, /* instance ID of the task */
SSTskId sTskId /* system task to use */
)
#else
PUBLIC S16 SAttachTTsk(ent, inst, sTskId)
Ent ent; /* entity ID of the task */
Inst inst; /* instance ID of the task */
SSTskId sTskId; /* system task to use */
#endif
{
S16 ret;
S16 i;
SsIdx idx;
SsSTskEntry *sTsk;
TRC1(SAttachTTsk);
#if (ERRCLASS & ERRCLS_INT_PAR)
/* check entity and instance range */
if (ent >= SS_MAX_ENT || inst >= SS_MAX_INST)
{
SSLOGERROR(ERRCLS_INT_PAR, ESS495, ERRZERO, "Invalid entity/instance");
RETVALUE(RFAILED);
}
/* check the system task index */
if ((SsIdx)sTskId >= SS_MAX_STSKS)
{
SSLOGERROR(ERRCLS_INT_PAR, ESS496, (ErrVal) sTskId,
"Invalid system task ID");
RETVALUE(RFAILED);
}
#endif
/* lock the system task table */
ret = SLock(&osCp.sTskTblLock);
if (ret != ROK)
{
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS497, (ErrVal) ret,
"Could not lock system task table");
#endif
RETVALUE(RFAILED);
}
sTsk = &osCp.sTskTbl[(SsIdx)sTskId];
#if (ERRCLASS & ERRCLS_INT_PAR)
/* verify that this system task exists */
if (sTsk->used == FALSE)
{
SUnlock(&osCp.sTskTblLock);
SSLOGERROR(ERRCLS_INT_PAR, ESS498, (ErrVal) sTskId,
"Unknown system task ID");
RETVALUE(RFAILED);
}
#endif
/* lock the system task entry */
if (!SS_CHECK_CUR_STSK(sTsk))
{
ret = SLock(&sTsk->lock);
if (ret != ROK)
{
SUnlock(&osCp.sTskTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS499, (ErrVal) ret,
"Could not lock system task entry");
#endif
RETVALUE(RFAILED);
}
}
/* if this system task is about to die, we don't attach */
if (sTsk->termPend == TRUE)
{
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
RETVALUE(RFAILED);
}
/* lock the TAPA task table */
SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
if (ret != ROK)
{
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
#if (ERRCLASS & ERRCLS_DEBUG)
SSLOGERROR(ERRCLS_DEBUG, ESS500, ERRZERO,
"Could not lock TAPA task table");
#endif
RETVALUE(RFAILED);
}
/* get the index of the TAPA task entry in the table */
idx = osCp.tTskIds[ent][inst];
#if (ERRCLASS & ERRCLS_INT_PAR)
/* check out the TAPA task ID */
if (idx == SS_TSKNC)
{
SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
SSLOGERROR(ERRCLS_INT_PAR, ESS501, ERRZERO, "Unknown task");
RETVALUE(RFAILED);
}
#endif
/* verify that this TAPA task is not already attached */
if (osCp.tTskTbl[idx].sTsk != NULLP)
{
SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
RETVALUE(RFAILED);
}
/* verify that there is space for another TAPA task */
if (sTsk->numTTsks == SS_MAX_TTSKS)
{
SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
RETVALUE(ROUTRES);
}
/* Find place for this TAPA task in the system task's list
* of TAPA tasks to run. Plug in this TAPA task.
*/
for (i = 0; i < SS_MAX_TTSKS; i++)
{
if (sTsk->tTsks[i] == SS_INVALID_IDX)
{
sTsk->tTsks[i] = idx;
sTsk->numTTsks++;
break;
}
}
/* Fill in the system task info in the TAPA task entry, so
* the TAPA task knows who's running it.
*/
osCp.tTskTbl[idx].sTsk = sTsk;
/* call the implementation to do anything implementation-specific */
ret = ssdAttachTTsk(&osCp.tTskTbl[idx]);
/* unlock the tables; we're done */
SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
if (!SS_CHECK_CUR_STSK(sTsk))
{
SUnlock(&sTsk->lock);
}
SUnlock(&osCp.sTskTblLock);
/* If the implementation didn't succeed, we have to undo everything.
* We call SDetachTTsk, to make it easier.
*/
if (ret != ROK)
{
SDetachTTsk(ent, inst);
RETVALUE(RFAILED);
}
RETVALUE(ROK);
} /* SAttachTTsk */
/*
*
* Fun: Detach TAPA task
*
* Desc: This function is used to detach a TAPA task from a
* system task. The system task will stop executing
* the TAPA task.
*
* Ret: ROK - ok
* RFAILED - failed, general (optional)
*
* Notes:
*
* File: ss_task.c
*
*/
#ifdef ANSI
PUBLIC S16 SDetachTTsk
(
Ent ent, /* entity ID of the task */
Inst inst /* instance ID of the task */
)
#else
PUBLIC S16 SDetachTTsk(ent, inst)
Ent ent; /* entity ID of the task */
Inst inst; /* instance ID of the task */
#endif
{
S16 ret;
S16 i;
SsIdx idx;
SsTTskEntry *tTsk;
SsSTskEntry *sTsk;
TRC1(SDetachTTsk);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -