⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ss_task.c

📁 中国石油二期加油站IC系统后台通讯软件
💻 C
📖 第 1 页 / 共 4 页
字号:
Ent ent;                        /* entity */
Inst inst;                      /* instance */
Ttype type;                     /* task type */
Prior prior;                    /* task priority */
PAIFS16 initTsk;                /* initialization function */
ActvTsk actvTsk;                /* activation function */
#endif
{
    S16 ret;
    SsTTskEntry *tTsk;


    TRC1(SRegTTsk);


#if (ERRCLASS & ERRCLS_INT_PAR)

    /* check entity and instance ranges */
    if (ent >= SS_MAX_ENT ||  inst >= SS_MAX_INST)
    {
        SSLOGERROR(ERRCLS_INT_PAR, ESS467, ERRZERO, "Invalid entity/instance");
        RETVALUE(RFAILED);
    }

    /* check activation function */
    if (actvTsk == NULLP)
    {
        SSLOGERROR(ERRCLS_INT_PAR, ESS468, ERRZERO, "Null pointer");
        RETVALUE(RFAILED);
    }

    /* check task type */
    if (type != TTNORM  &&  type != TTPERM)
    {
        SSLOGERROR(ERRCLS_INT_PAR, ESS469, ERRZERO, "Invalid task type");
    }

    /* check task priority */
    if (prior > PRIOR3)
    {
        SSLOGERROR(ERRCLS_INT_PAR, ESS470, ERRZERO, "Invalid task priority");
        RETVALUE(RFAILED);
    }
#endif


    /* Acquire the counting semaphore for all other system
     *  tasks (this call is either running in one system task's
     *  context, or in SInit()'s context). Once we have all of
     *  them, SPstTsk() cannot run, so we can do things to the
     *  TAPA task table.
     */
    SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
    if (ret != ROK)
    {

#if (ERRCLASS & ERRCLS_DEBUG)
        SSLOGERROR(ERRCLS_DEBUG, ESS471, ERRZERO,
                   "Could not lock TAPA task table");
#endif

        RETVALUE(RFAILED);
    }


#if (ERRCLASS & ERRCLS_DEBUG)
    /* check count of tasks */
    if (osCp.numTTsks == SS_MAX_TTSKS)
    {
        SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
        SSLOGERROR(ERRCLS_DEBUG, ESS472, ERRZERO, "Too many tasks");
        RETVALUE(ROUTRES);
    }

    /* check if entity and instance already registered */
    if (osCp.tTskIds[ent][inst] != SS_TSKNC)
    {
        SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);
        SSLOGERROR(ERRCLS_DEBUG, ESS473, ERRZERO,
                   "Entity and instance already registered");
        RETVALUE(RFAILED);
    }
#endif


    /*  We fill up the current available slot with all the
     *  information we've been given. Update table information,
     *  and the task is registered.
     */
    tTsk = &osCp.tTskTbl[osCp.nxtTTskEntry];
    tTsk->used     = TRUE;
    tTsk->ent      = ent;
    tTsk->inst     = inst;
    tTsk->tskType  = type;
    tTsk->tskPrior = prior;
    tTsk->initTsk  = initTsk;
    tTsk->actvTsk  = actvTsk;
    tTsk->sTsk     = NULLP;

    osCp.tTskIds[ent][inst] = osCp.nxtTTskEntry;
    osCp.nxtTTskEntry = tTsk->nxt;
    osCp.numTTsks++;


    /* Activate initialization function, if present. Like
     *  SRegInit(), we use hard-coded parameters. Note: we
     *  assume that the initialization function is not
     *  going to call SRegTTsk() or SPstTsk(). If it does,
     *  this thread will freeze up as we are holding the
     *  TAPA task table counting semaphore.
     */
    if (initTsk != NULLP)
        (Void)(*initTsk)(ent, inst, DFLT_REGION, PWR_UP);


    /* unlock the table */
    SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);


    RETVALUE(ROK);
} /* SRegTTsk */


/*
*
*       Fun:   Deregister TAPA task
*
*       Desc:  This function is used to deregister a TAPA task.
*              All information about the task is removed from the
*              task table.
*
*       Ret:   ROK      - ok
*              RFAILED  - failed, general (optional)
*
*       Notes:
*
*       File:  ss_task.c
*
*/
#ifdef ANSI
PUBLIC S16 SDeregTTsk
(
Ent ent,                        /* entity */
Inst inst                       /* instance */
)
#else
PUBLIC S16 SDeregTTsk(ent, inst)
Ent ent;                        /* entity */
Inst inst;                      /* instance */
#endif
{
    S16          ret;
    S16          n;
    SsIdx        idx;
    SsTTskEntry *tTsk;
    SsSTskEntry *sTsk;
    SsTmrEntry  *tmr;


    TRC1(SDeregTTsk);


#if (ERRCLASS & ERRCLS_INT_PAR)

    /* check entity and instance ranges */
    if (ent >= SS_MAX_ENT ||  inst >= SS_MAX_INST)
    {
        SSLOGERROR(ERRCLS_INT_PAR, ESS474, ERRZERO, "Invalid entity/instance");
        RETVALUE(RFAILED);
    }
#endif


    /* We deregister all timers for this TAPA task, since it's going
     *  away now. Lock the timer table and iterate through it, removing
     *  all timers owned by this task.
     */
    if (SLock(&osCp.tmrTblLock) != ROK)
    {
#if (ERRCLASS & ERRCLS_DEBUG)
        SSLOGERROR(ERRCLS_DEBUG, ESS475, ERRZERO,
                   "Could not lock timer table");
#endif
        RETVALUE(RFAILED);
    }

    for (idx = 0;  idx < SS_MAX_TMRS;  idx++)
    {
        if ((osCp.tmrTbl[idx].ownerEnt == ent) &&  
            (osCp.tmrTbl[idx].ownerInst == inst))
        {
            /* shut down this timer */
            tmr = &osCp.tmrTbl[idx];
            if (ssdDeregTmr(tmr) == ROK)
            {
                tmr->used      = FALSE;
                tmr->tmrId     = 0;
                tmr->ownerEnt  = ENTNC;
                tmr->ownerInst = INSTNC;
                tmr->interval  = 0;
                tmr->tmrActvFn = NULLP;

                tmr->nxt = osCp.nxtTmrEntry;
                osCp.nxtTmrEntry = (SsIdx)idx;
                osCp.numTmrs--;
            } else
            {
                SUnlock(&osCp.tmrTblLock);

#if (ERRCLASS & ERRCLS_DEBUG)
                SSLOGERROR(ERRCLS_DEBUG, ESS476, ERRZERO,
                           "Could not deregister task's timer(s)");
#endif
                RETVALUE(RFAILED);

            }
        }
    }

    SUnlock(&osCp.tmrTblLock);


    /* Now, we grab the system task table lock and the locks
     *  for all the system tasks. This will prevent them from
     *  examining the TAPA task index table while we're changing
     *  it. This is only necessary for one case, where a task is
     *  detached from a system task and is being deregistered,
     *  but messages for it are still in the system task's demand
     *  queue.
     */
    ret = SLock(&osCp.sTskTblLock);
    if (ret != ROK)
    {

#if (ERRCLASS & ERRCLS_DEBUG)
        SSLOGERROR(ERRCLS_DEBUG, ESS477, (ErrVal) ret,
                   "Could not lock system task table");
#endif

        RETVALUE(RFAILED);
    }

    for (n = 0;  n < SS_MAX_STSKS;  n++)
    {
        if (osCp.sTskTbl[n].used)
        {
            if (!SS_CHECK_CUR_STSK(&osCp.sTskTbl[n]))
            {
                ret = SLock(&osCp.sTskTbl[n].lock);
                if (ret != ROK)
                {
#if (ERRCLASS & ERRCLS_DEBUG)
                    SSLOGERROR(ERRCLS_DEBUG, ESS478, (ErrVal) ret,
                               "Could not lock system task entry");
#endif

                    /* unlock everything we've locked */
                    while (n > 0)
                    {
                        n--;
                        if (osCp.sTskTbl[n].used)
                        {
                            if (!SS_CHECK_CUR_STSK(&osCp.sTskTbl[n]))
                            {
                                SUnlock(&osCp.sTskTbl[n].lock);
                            }
                        }
                    }
                    SUnlock(&osCp.sTskTblLock);

                    RETVALUE(RFAILED);
                }
            }
        }
    }


    /* Acquire the counting semaphore for all TAPA tasks. Once
     *  we have all of them, both SPstTsk() and SRegTTsk() cannot
     *  run, so we can do things to the TAPA task table.
     */
    SS_ACQUIRE_ALL_SEMA(&osCp.tTskTblSem, ret);
    if (ret != ROK)
    {
        /* unlock all the system task entries */
        for (n = 0;  n < SS_MAX_STSKS;  n++)
        {
            if (osCp.sTskTbl[n].used)
            {
                if (!SS_CHECK_CUR_STSK(&osCp.sTskTbl[n]))
                {
                    SUnlock(&osCp.sTskTbl[n].lock);
                }
            }
        }

        /* unlock the system task table */
        SUnlock(&osCp.sTskTblLock);

#if (ERRCLASS & ERRCLS_DEBUG)
        SSLOGERROR(ERRCLS_DEBUG, ESS479, ERRZERO,
                   "Could not lock TAPA task table");
#endif

        RETVALUE(RFAILED);
    }


    /* get out the TAPA task entry */
    idx = osCp.tTskIds[ent][inst];

    /* make sure this TAPA task exists */
    if (idx == SS_TSKNC)
    {
        SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);

        /* unlock all the system task entries */
        for (n = 0;  n < SS_MAX_STSKS;  n++)
        {
            if (osCp.sTskTbl[n].used)
            {
                if (!SS_CHECK_CUR_STSK(&osCp.sTskTbl[n]))
                {
                    SUnlock(&osCp.sTskTbl[n].lock);
                }
            }
        }

        /* unlock the system task table */
        SUnlock(&osCp.sTskTblLock);

        SSLOGERROR(ERRCLS_INT_PAR, ESS480, ERRZERO, "Unknown task");
        RETVALUE(RFAILED);
    }

    tTsk = &osCp.tTskTbl[idx];


    /* We check the sTsk element; if it is not NULLP, the
     *  task is attached. So we have to detach it before
     *  deregistering the task.
     */
    if (tTsk->sTsk != NULLP)
    {
        sTsk = tTsk->sTsk;

        tTsk->sTsk = NULLP;

        for (n = 0;  n < SS_MAX_TTSKS;  n++)
        {
            if (sTsk->tTsks[n] == idx)
            {
                sTsk->tTsks[n] = SS_INVALID_IDX;
                sTsk->numTTsks--;
                break;
            }
        }

        /* call the implementation to detach the task */
        ssdDetachTTsk(tTsk);
    }


    /* Now we empty the entry for this task and update the table
     *  information
     */
    osCp.tTskIds[ent][inst] = SS_TSKNC;

    tTsk->used    = FALSE;
    tTsk->ent     = ENTNC;
    tTsk->inst    = INSTNC;
    tTsk->tskType = TTUND;
    tTsk->initTsk = NULLP;
    tTsk->actvTsk = NULLP;
    tTsk->sTsk    = NULLP;

    tTsk->nxt = osCp.nxtTTskEntry;
    osCp.nxtTTskEntry = idx;
    osCp.numTTsks--;


    /* unlock the TAPA task table */
    SS_RELEASE_ALL_SEMA(&osCp.tTskTblSem);

    /* unlock all the system task entries */
    for (n = 0;  n < SS_MAX_STSKS;  n++)
    {
        if (osCp.sTskTbl[n].used)
        {
            if (!SS_CHECK_CUR_STSK(&osCp.sTskTbl[n]))
            {
                SUnlock(&osCp.sTskTbl[n].lock);
            }
        }
    }

    /* unlock the system task table */
    SUnlock(&osCp.sTskTblLock);


    RETVALUE(ROK);
} /* SDeregTTsk */


/*
*
*       Fun:   Create system task
*
*       Desc:  This function is used to create a system task. An
*              entry is located in the system task table and the
*              implementation-specific function is called.
*
*       Ret:   ROK      - ok
*              RFAILED  - failed, general (optional)
*              ROUTRES  - failed, out of resources (optional)
*
*       Notes:
*
*       File:  ss_task.c
*
*/
#ifdef ANSI
PUBLIC S16 SCreateSTsk
(
SSTskPrior tskPrior,            /* task priority */
SSTskId *tskId                  /* filled in with system task ID */
)
#else
PUBLIC S16 SCreateSTsk(tskPrior, tskId)
SSTskPrior tskPrior;            /* task priority */
SSTskId *tskId;                 /* filled in with system task ID */
#endif
{
    S16 ret;
    SsSTskEntry *sTsk;


    TRC1(SCreateSTsk);


#if (ERRCLASS & ERRCLS_INT_PAR)

    /* check task ID pointer */
    if (tskId == NULLP)
    {
        SSLOGERROR(ERRCLS_INT_PAR, ESS481, ERRZERO, "Null pointer");
        RETVALUE(RFAILED);
    }

    /* check system task priority */
    if (tskPrior > SS_LOWEST_STSK_PRIOR)
    {
        SSLOGERROR(ERRCLS_INT_PAR, ESS482, ERRZERO,
                   "Invalid system task priority");
        RETVALUE(RFAILED);
    }
#endif


    /* lock the system task table */
    ret = SLock(&osCp.sTskTblLock);
    if (ret != ROK)
    {

#if (ERRCLASS & ERRCLS_DEBUG)
        SSLOGERROR(ERRCLS_DEBUG, ESS483, (ErrVal) ret,
                   "Could not lock system task table");
#endif

        RETVALUE(RFAILED);
    }


#ifdef SS_SINGLE_THREADED
    /* When singlethreaded, we only need to create one... */
    if (osCp.numSTsks == 1)
    {
        *tskId = 0;
        osCp.sTskTbl[0].termPend = FALSE;
        SUnlock(&osCp.sTskTblLock);

        RETVALUE(ROK);
    }
#endif /* SS_SINGLE_THREADED */


    /* check count of system tasks */
    if (osCp.numSTsks == SS_MAX_STSKS)
    {
        SUnlock(&osCp.sTskTblLock);

#if (ERRCLASS & ERRCLS_ADD_RES)
        SSLOGERROR(ERRCLS_ADD_RES, ESS484, ERRZERO, "Too many system tasks");
#endif

        RETVALUE(ROUTRES);
    }


    /* initialize the system task entry with the information we have */
    sTsk = &osCp.sTskTbl[osCp.nxtSTskEntry];

    /* store the system task priority */
    sTsk->tskPrior = tskPrior;

    /* initialize the demand queue */
    if (ssInitDmndQ(&sTsk->dQ) != ROK)
    {
        SUnlock(&osCp.sTskTblLock);

#if (ERRCLASS & ERRCLS_DEBUG)
        SSLOGERROR(ERRCLS_DEBUG, ESS485, (ErrVal) ret,
                   "Could not initialize demand queue");
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -