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

📄 siglib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (pSigpend->sigp_info.si_code == SI_QUEUE)	    {	    *(struct sigpend **)pSigpend = _pSigQueueFreeHead;	    _pSigQueueFreeHead = pSigpend;	    }	}    if (pSigTcb->sigt_qhead[sig].sigq_next == &pSigTcb->sigt_qhead[sig])	pSigTcb->sigt_pending &= ~mask;    return (sig);    }/********************************************************************************* sigWindPendKill - add a signal to the set of pending signals** NOTE: YOU MUST BE IN THE KERNEL.*/static void sigWindPendKill    (    WIND_TCB		*pTcb,    struct sigpend	*pSigPend    )    {    int			signo = pSigPend->sigp_info.si_signo;    struct sigtcb	*pSigTcb;    void		(*func)();    unsigned		mask;    /*     * Check to see if the task has the signal structure.  If it does     * not, we pretend the task is ignoring them.     */    if ((pSigTcb = pTcb->pSignalInfo) == NULL)	return;    /*     * If task is waiting for signal, deliver it by waking up the task.     */    if ((pSigTcb->sigt_wait != NULL) &&	(sigismember(&pSigTcb->sigt_wait->sigw_set, signo) == 1) &&	(Q_FIRST(&pSigTcb->sigt_wait->sigw_wait) != NULL))	{	pSigTcb->sigt_wait->sigw_info = pSigPend->sigp_info;#ifdef WV_INSTRUMENTATION        /* windview - level 2 event logging */  	EVT_TASK_1 (EVENT_OBJ_SIGKILL, pTcb); /* log event */#endif	windPendQGet (&pSigTcb->sigt_wait->sigw_wait);	/*	 * Mark task as no longer waiting	 */	pSigTcb->sigt_wait = NULL;	return;	}    /*     * The default action for signals is to ignore them, in posix     * it is to kill the process.     */    func = pSigTcb->sigt_vec[signo].sa_handler;    if (func == SIG_DFL)	return;			/* should maybe kill the task */    /*     * Check to see if signal should be ignored.     */    if (func == SIG_IGN)	return;    /*     * Check to see if signal should be queued up because they are being     * blocked.     */    mask = sigmask(signo);    if (pSigTcb->sigt_blocked & mask)	{	/*	 * kill signals just get a bit to say a signal has come	 */	if (pSigPend->sigp_info.si_code == SI_KILL)	    {	    pSigTcb->sigt_kilsigs |= mask;	    pSigTcb->sigt_pending |= mask;	    }	/*	 * if the signal is all ready queued, mark it as overrun	 */	else if (pSigPend->sigp_q.sigq_next != NULL)	    pSigPend->sigp_active_overruns++;	/*	 * must be a signal to queue	 */	else	    {	    struct sigq *head = &pSigTcb->sigt_qhead[signo];	    /*	     * alloc buffer for sigqueue	     */	    if (pSigPend->sigp_info.si_code == SI_QUEUE)		{		struct sigpend *pTmp = _pSigQueueFreeHead;		_pSigQueueFreeHead = *(struct sigpend **)_pSigQueueFreeHead;		*pTmp = *pSigPend;		pSigPend = pTmp;		}	    pSigPend->sigp_q.sigq_prev = head->sigq_prev;	    pSigPend->sigp_q.sigq_next = head;	    pSigPend->sigp_q.sigq_prev->sigq_next = &pSigPend->sigp_q;	    head->sigq_prev = &pSigPend->sigp_q;	    pSigTcb->sigt_pending |= mask;	    pSigPend->sigp_tcb = pSigTcb;	    }	return;	}    /*     * Force delivery of the signal.     */    if (taskIdCurrent != pTcb)	{	int args[2];	struct sigcontext *pCtx;#if _STACK_DIR == _STACK_GROWS_DOWN	pCtx = (struct sigcontext *) MEM_ROUND_DOWN	       (((struct sigcontext *)_sigCtxStackEnd (&pTcb->regs)) - 1);#else	taskRegsStackToTcb (pTcb);	pCtx = (struct sigcontext *)	     MEM_ROUND_UP(_sigCtxStackEnd (&pTcb->regs));#endif	args[0] = 1;	args[1] = (int)pCtx;	/*	 * Mark task as no longer waiting	 */	pSigTcb->sigt_wait     = NULL;	pCtx->sc_onstack       = 0;	pCtx->sc_restart       = sigWindRestart (pTcb);	pCtx->sc_mask          = pSigTcb->sigt_blocked;	pSigTcb->sigt_blocked |= (pSigTcb->sigt_vec[signo].sa_mask | mask);	pCtx->sc_info          = pSigPend->sigp_info;	pCtx->sc_regs          = pTcb->regs;#if CPU_FAMILY == MC680X0	pCtx->sc_fformat = pTcb->foroff;#endif#if CPU == I960KB	bcopy (pTcb->intResumptionRec, pCtx->sc_resumption, 16);#endif	pCtx->sc_pregs         = pSigPend->sigp_pregs;#if _STACK_DIR == _STACK_GROWS_DOWN	_sigCtxSetup (&pTcb->regs, (void *)STACK_ROUND_DOWN(pCtx), sigWrapper, args);#else	_sigCtxSetup (&pTcb->regs, (void *)STACK_ROUND_UP(pCtx + 1), sigWrapper, args);#endif	}    else	{	struct sigcontext Ctx;	Ctx.sc_onstack         = 0;	Ctx.sc_restart         = 0;	Ctx.sc_mask            = pSigTcb->sigt_blocked;	pSigTcb->sigt_blocked |= (pSigTcb->sigt_vec[signo].sa_mask | mask);	Ctx.sc_info            = pSigPend->sigp_info;#if CPU_FAMILY == MC680X0	Ctx.sc_fformat         = pTcb->foroff;#endif#if CPU == I960KB	bcopy (pTcb->intResumptionRec, Ctx.sc_resumption, 16);#endif	Ctx.sc_pregs           = pSigPend->sigp_pregs;	windExit ();				/* KERNEL EXIT */	if (_sigCtxSave(&Ctx.sc_regs) == 0)	    {	    _sigCtxRtnValSet (&Ctx.sc_regs, 1);	    sigWrapper(&Ctx);	    }	kernelState = TRUE;			/* KERNEL ENTER */	}    }/********************************************************************************* sigPendKill - send a queue signal** NOMANUAL** RETURNS: nothing*/int sigPendKill    (    int			tid,    struct sigpend	*pSigPend    )    {#if 0    /*     * for now, blindly assume it is valid.     */    if (!issig (pSigPend))	{	errnoSet (EINVAL);	return (ERROR);	}#endif    if (kernelState || (INT_CONTEXT () && (int) taskIdCurrent == tid))	{	if (TASK_ID_VERIFY (tid) != OK)	    {	    errnoSet (EINVAL);	    return (ERROR);	    }	excJobAdd ((VOIDFUNCPTR) sigPendKill, tid, (int) pSigPend, 0, 0, 0, 0);	return (OK);	}    kernelState = TRUE;				/* KERNEL ENTER */     if (TASK_ID_VERIFY (tid) != OK)		/* verify task */	{	windExit ();				/* KERNEL EXIT */	errnoSet (EINVAL);	return (ERROR);	}    sigWindPendKill ((WIND_TCB *) tid, pSigPend);	/* signal a task */     windExit ();				/* KERNEL EXIT */     return (OK);    }/********************************************************************************* sigPendInit - init a queue signal** NOMANUAL** RETURNS: nothing*/void sigPendInit    (    struct sigpend	*pSigPend    )    {    pSigPend->sigp_q.sigq_prev = pSigPend->sigp_q.sigq_next = NULL;    pSigPend->sigp_overruns = 0;     pSigPend->sigp_pregs = NULL;     }/********************************************************************************* sigPendDestroy - destory a queue signal** NOMANUAL** RETURNS: OK or ERROR*/int sigPendDestroy    (    struct sigpend	*pSigPend    )    {    if (INT_RESTRICT () != OK)	return (ERROR);    pSigPend->sigp_overruns = 0;     kernelState = TRUE;				/* KERNEL ENTER */    if (pSigPend->sigp_q.sigq_next != 0)	{	/*	 * Clear sigpending if last one on chain. (and there was no kilsigs)	 */	if (pSigPend->sigp_q.sigq_next == pSigPend->sigp_q.sigq_prev)	    pSigPend->sigp_tcb->sigt_pending &=    		(pSigPend->sigp_tcb->sigt_kilsigs |		~sigmask(pSigPend->sigp_info.si_signo));	pSigPend->sigp_q.sigq_next->sigq_prev = pSigPend->sigp_q.sigq_prev;	pSigPend->sigp_q.sigq_prev->sigq_next = pSigPend->sigp_q.sigq_next;	pSigPend->sigp_q.sigq_prev = pSigPend->sigp_q.sigq_next = NULL;	}    windExit ();				/* KERNEL EXIT */    return (OK);    }/********************************************************************************* sigWindKill - do the dirty work of sending a signal.** NOTE: YOU MUST BE IN THE KERNEL.*/static void sigWindKill    (    WIND_TCB		*pTcb,    int			signo    )    {    struct sigpend pend;    pend.sigp_info.si_signo	      = signo;    pend.sigp_info.si_code            = SI_KILL;    pend.sigp_info.si_value.sival_int = 0;    sigWindPendKill(pTcb, &pend);    }/********************************************************************************* sigWindRestart - test the state of a task** Test the state of a task you are sending a signal to.  If it is* pended, tell it to restart itself after it has returned.** NOTE: YOU MUST BE IN THE KERNEL.*/static int sigWindRestart    (    WIND_TCB		*pTcb    )    {    int delay = WAIT_FOREVER;    int status;			/* Q_REMOVE return value */    if ((pTcb->status & (WIND_PEND | WIND_DELAY)) != 0)	{	taskRtnValueSet (pTcb, RESTART);	if ((pTcb->status & WIND_DELAY) != 0)	    {	    pTcb->status &= ~WIND_DELAY;	    Q_REMOVE (&tickQHead, &pTcb->tickNode);	/* remove from queue */	    delay = Q_KEY (&tickQHead, &pTcb->tickNode, 1);	    }	if ((pTcb->status & WIND_PEND) != 0)	    {	    pTcb->pPriMutex = NULL;			/* clear pPriMutex */	    pTcb->status   &= ~WIND_PEND;		/* turn off pend bit */	    status = Q_REMOVE (pTcb->pPendQ, pTcb);	/* out of pend queue */	    /* 	     * If task was pended on a shared semaphore its shared TCB 	     * could have been remove by a semGive on another CPU.  In that 	     * case Q_REMOVE returns ALREADY_REMOVED, What we have to do	     * is set task return value to OK to avoid task to be restarted.	     * Q_REMOVE can also return ERROR if it was unable to take 	     * the shared semaphore lock to remove the shared TCB.	     * In that case we set task return value to ERROR and 	     * errorStatus to S_smObjLib_LOCK_TIMEOUT.	     */	    switch (status)		{		case ALREADY_REMOVED :		    {		    taskRtnValueSet (pTcb, OK);		    break;		    }		case ERROR :		    {		    taskRtnValueSet (pTcb, ERROR);		    pTcb->errorStatus = S_smObjLib_LOCK_TIMEOUT;		    break;		    }		}	    }	if (pTcb->status == WIND_READY)			/* task is now ready */	    Q_PUT (&readyQHead, pTcb, pTcb->priority);	}    return (delay);    }/********************************************************************************* sigExcSend - signal a task that has an exception** RETURNS: nothing*/static void sigExcSend    (    int		signo,    int		code,    REG_SET	*pRegSet    )    {    struct sigpend pend;    REG_SET *pTmpRegSet;    pTmpRegSet = taskIdCurrent->pExcRegSet;    taskIdCurrent->pExcRegSet = 0;    sigPendInit (&pend);    pend.sigp_info.si_signo	      = signo;    pend.sigp_info.si_code            = SI_SYNC;    pend.sigp_info.si_value.sival_int = code;    pend.sigp_pregs                   = pRegSet;    sigPendKill ((int) taskIdCurrent, &pend);    sigPendDestroy (&pend);    taskIdCurrent->pExcRegSet = pTmpRegSet;    }/********************************************************************************* sigExcKill - signal a task that has an exception** RETURNS: nothing*/static void sigExcKill    (    int      faultType,    int      code,    REG_SET  *pRegSet    )    {    extern struct sigfaulttable _sigfaulttable[];    struct sigfaulttable *pFTab;    for (pFTab = &_sigfaulttable[0]; 	 !((pFTab->sigf_fault == 0) && (pFTab->sigf_signo == 0));	 pFTab++)	{	if (pFTab->sigf_fault == faultType)	    {	    sigExcSend (pFTab->sigf_signo, code, pRegSet);	    return;	    }	}    /* not found in the table */    if (pFTab->sigf_signo != 0)        sigExcSend (pFTab->sigf_signo, code, pReg

⌨️ 快捷键说明

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