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

📄 synch.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 2 页
字号:
 * This service gives the ownership of a synchronization object to the * thread which is currently leading the object's pending list. The * sleeping thread is unblocked, but no action is taken regarding the * previous owner of the resource. * * This service should be called by upper interfaces wanting to signal * the given resource so that a single waiter is resumed. * * @param synch The descriptor address of the synchronization object * whose ownership is changed. * * @return The descriptor address of the unblocked thread. * * Side-effects: * * - The effective priority of the previous resource owner might be * lowered to its base priority value as a consequence of the priority * inheritance boost being cleared. * * - The synchronization object ownership is transfered to the * unblocked thread. * * - This routine does not call the rescheduling procedure. * * Context: This routine must be called on behalf of a thread or IST * context. */xnthread_t *xnsynch_wakeup_one_sleeper (xnsynch_t *synch){    xnthread_t *thread = NULL, *lastowner = synch->owner;    xnpholder_t *holder;    spl_t s;    splhigh(s);    holder = getpq(xnsynch_wait_queue(synch));    if (holder)	{	thread = link2thread(holder,plink);	thread->wchan = NULL;	synch->owner = thread;	xnpod_resume_thread(thread,XNPEND);	}    else	synch->owner = NULL;    if (testbits(synch->status,XNSYNCH_CLAIMED))	xnsynch_clear_boost(synch,lastowner);    splexit(s);    xnarch_post_graph_if(synch,0,countpq(&synch->pendq) == 0);    return thread;}/*!  * \fn void xnsynch_wakeup_this_sleeper(xnsynch_t *synch, xnpholder_t *holder); * \brief Give the resource ownership to a given waiting thread. * * This service gives the ownership of a given synchronization object * to a specific thread which is currently pending on it. The sleeping * thread is unblocked from its pending state. No action is taken * regarding the previous resource owner. * * This service should be called by upper interfaces wanting to signal * the given resource so that a specific waiter is resumed. * * @param synch The descriptor address of the synchronization object * whose ownership is changed. * * @param holder The link holder address of the thread to unblock * (&thread->plink) which MUST currently be linked to the * synchronization object's pending queue (i.e. synch->pendq). * * @return The link address of the unblocked thread in the * synchronization object's pending queue. * * Side-effects: * * - The effective priority of the previous resource owner might be * lowered to its base priority value as a consequence of the priority * inheritance boost being cleared. * * - The synchronization object ownership is transfered to the * unblocked thread. * * - This routine does not call the rescheduling procedure. * * Context: This routine must be called on behalf of a thread or IST * context. */xnpholder_t *xnsynch_wakeup_this_sleeper (xnsynch_t *synch,					  xnpholder_t *holder){    xnthread_t *thread, *lastowner = synch->owner;    xnpholder_t *nholder;    spl_t s;    splhigh(s);    nholder = poppq(xnsynch_wait_queue(synch),holder);    thread = link2thread(holder,plink);    thread->wchan = NULL;    synch->owner = thread;    xnpod_resume_thread(thread,XNPEND);    if (testbits(synch->status,XNSYNCH_CLAIMED))	xnsynch_clear_boost(synch,lastowner);    splexit(s);    xnarch_post_graph_if(synch,0,countpq(&synch->pendq) == 0);    return nholder;}/*!  * \fn void xnsynch_flush(xnsynch_t *synch, xnflags_t reason); * \brief Unblock all waiters pending on a resource. * * This service atomically releases all threads which currently sleep * on a given resource. * * This service should be called by upper interfaces under * circumstances requiring that the pending queue of a given resource * is cleared, such as before the resource is deleted. * * @param synch The descriptor address of the synchronization object * whose ownership is changed. * * @param reason Some flags to set in the status mask of every * unblocked thread. The following bits are pre-defined by the * nanokernel: * * - XNRMID should be set to indicate that the synchronization object * is about to be destroyed (see xnpod_resume_thread()). * * - XNBREAK should be set to indicate that the wait has been forcibly * interrupted (see xnpod_unblock_thread()). * * @return XNSYNCH_RESCHED is returned if at least one thread * is unblocked, which means the caller should invoke xnpod_schedule() * for applying the new scheduling state. Otherwise, XNSYNCH_DONE is * returned. * * Side-effects: * * - The effective priority of the previous resource owner might be * lowered to its base priority value as a consequence of the priority * inheritance boost being cleared. * * - The synchronization object is no more owned by any thread. * * - This routine does not call the rescheduling procedure. * * Context: This routine must be called on behalf of a thread or IST * context. */int xnsynch_flush (xnsynch_t *synch, xnflags_t reason){    xnpholder_t *holder;    int status;    spl_t s;    splhigh(s);    status = countpq(&synch->pendq) > 0 ? XNSYNCH_RESCHED : XNSYNCH_DONE;    while ((holder = getpq(&synch->pendq)) != NULL)	{	xnthread_t *sleeper = link2thread(holder,plink);	setbits(sleeper->status,reason);	sleeper->wchan = NULL;	xnpod_resume_thread(sleeper,XNPEND);	}    if (testbits(synch->status,XNSYNCH_CLAIMED))	{	xnsynch_clear_boost(synch,synch->owner);	status = XNSYNCH_RESCHED;	}    synch->owner = NULL;    splexit(s);    xnarch_post_graph_if(synch,0,countpq(&synch->pendq) == 0);    return status;}/*!  * \fn void xnsynch_forget_sleeper(xnthread_t *thread); * \brief Abort a wait for a resource - INTERNAL. * * Performs all the necessary housekeeping chores to stop a thread * from waiting on a given synchronization object. * * @param thread The descriptor address of the affected thread. * * When the trace support is enabled (i.e. MVM), the idle state is * posted to the synchronization object's state diagram (if any) * whenever no thread remains blocked on it. The real-time interfaces * must ensure that such condition (i.e. EMPTY/IDLE) is mapped to * state #0. */void xnsynch_forget_sleeper (xnthread_t *thread) /* INTERNAL */{    xnsynch_t *synch = thread->wchan;    clrbits(thread->status,XNPEND);    thread->wchan = NULL;    removepq(&synch->pendq,&thread->plink);    if (testbits(synch->status,XNSYNCH_CLAIMED))	{	/* Find the highest priority needed to enforce the PIP. */	xnthread_t *owner = synch->owner;	int rprio;	if (countpq(&synch->pendq) == 0)	    /* No more sleepers: clear the boost. */	    xnsynch_clear_boost(synch,owner);	else if (getheadpq(&synch->pendq)->prio !=		getheadpq(&owner->claimq)->prio)		{		/* Reorder the claim queue, and lower the priority to the		   required minimum needed to prevent priority		   inversion. */		removepq(&owner->claimq,&synch->link);		insertpqf(&owner->claimq,			  &synch->link,			  getheadpq(&synch->pendq)->prio);		rprio = getheadpq(&owner->claimq)->prio;		if (xnpod_priocompare(rprio,owner->cprio) < 0)		    xnsynch_renice_thread(owner,rprio);		}	}    xnarch_post_graph_if(synch,0,countpq(&synch->pendq) == 0);}/*!  * \fn void xnsynch_release_all_ownerships(xnthread_t *thread); * \brief Release all ownerships - INTERNAL. * * This call is used internally to release all the ownerships obtained * by a thread on synchronization objects. This routine must be * entered interrupts off. * * @param thread The descriptor address of the affected thread. */void xnsynch_release_all_ownerships (xnthread_t *thread) /* INTERNAL */{    xnpholder_t *holder, *nholder;    xnsynch_t *synch;    holder = getheadpq(&thread->claimq);    while ((synch = link2synch(holder)) != NULL)	{	/* Since xnsynch_wakeup_one_sleeper() alters the claim queue, we	   need to be conservative while skulking it. */	nholder = nextpq(&thread->claimq,holder);	if (!testbits(synch->status,XNSYNCH_KMUTEX))	    xnsynch_wakeup_one_sleeper(synch);	holder = nholder;	}}/*@}*/EXPORT_SYMBOL(xnsynch_flush);EXPORT_SYMBOL(xnsynch_forget_sleeper);EXPORT_SYMBOL(xnsynch_init);EXPORT_SYMBOL(xnsynch_release_all_ownerships);EXPORT_SYMBOL(xnsynch_renice_sleeper);EXPORT_SYMBOL(xnsynch_sleep_on);EXPORT_SYMBOL(xnsynch_wakeup_one_sleeper);EXPORT_SYMBOL(xnsynch_wakeup_this_sleeper);

⌨️ 快捷键说明

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