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

📄 synch.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 2 页
字号:
/*!\file synch.c * \brief Thread synchronization services. * \author Philippe Gerum * * Copyright (C) 2001,2002,2003 Philippe Gerum <rpm@xenomai.org>. * * Xenomai is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Xenomai is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Xenomai; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * As a special exception, the RTAI project gives permission * for additional uses of the text contained in its release of * Xenomai. * * The exception is that, if you link the Xenomai libraries with other * files to produce an executable, this does not by itself cause the * resulting executable to be covered by the GNU General Public License. * Your use of that executable is in no way restricted on account of * linking the Xenomai libraries code into it. * * This exception does not however invalidate any other reasons why * the executable file might be covered by the GNU General Public * License. * * This exception applies only to the code released by the * RTAI project under the name Xenomai.  If you copy code from other * RTAI project releases into a copy of Xenomai, as the General Public * License permits, the exception does not apply to the code that you * add in this way.  To avoid misleading anyone as to the status of * such modified files, you must delete this exception notice from * them. * * If you write modifications of your own for Xenomai, it is your * choice whether to permit this exception to apply to your * modifications. If you do not wish that, delete this exception * notice. * * \ingroup synch *//*! * \ingroup xenomai * \defgroup synch Thread synchronization services. * * Thread synchronization services. * *@{*/#include <stdarg.h>#include "rtai_config.h"#include "xenomai/pod.h"#include "xenomai/mutex.h"#include "xenomai/synch.h"#include "xenomai/thread.h"#include "xenomai/module.h"/*!  * \fn void xnsynch_init(xnsynch_t *synch, xnflags_t flags); * \brief Initialize a synchronization object. * * Initializes a new specialized object which can subsequently be * used to synchronize real-time activities. Xenomai provides a basic * synchronization object which can be used to build higher resource * objects. Xenomai threads can wait for and signal such objects in * order to synchronize their activities. * * This object has built-in support for priority inheritance. * * @param synch The address of a synchronization object descriptor * Xenomai will use to store the object-specific data.  This * descriptor must always be valid while the object is active * therefore it must be allocated in permanent memory. * * @param flags A set of creation flags affecting the operation. The * valid flags are: * * - XNSYNCH_PRIO causes the threads waiting for the resource to pend * in priority order. Otherwise, FIFO ordering is used (XNSYNCH_FIFO). * * - XNSYNCH_PIP causes the priority inheritance mechanism to be * automatically activated when a priority inversion is detected among * threads using this object. Otherwise, no priority inheritance takes * place upon priority inversion (XNSYNCH_NOPIP). * * Side-effect: This routine does not call the rescheduling procedure. * * Context: This routine must be called on behalf of a thread context. */void xnsynch_init (xnsynch_t *synch,		   xnflags_t flags){    initph(&synch->link);    if (flags & XNSYNCH_PIP)	flags |= XNSYNCH_PRIO;	/* Obviously... */    synch->status = flags;    synch->owner = NULL;    initpq(&synch->pendq,xnpod_get_qdir(nkpod));    xnarch_init_display_context(synch);}/* * xnsynch_renice_thread() -- This service is used by the PIP code to * raise/lower a thread's priority. The thread's base priority value * is _not_ changed and if ready, the thread is always moved at the * end of its priority group. */static inline void xnsynch_renice_thread (xnthread_t *thread, int prio){    thread->cprio = prio;    if (thread->wchan)	/* Ignoring the XNDREORD flag on purpose here. */	xnsynch_renice_sleeper(thread);    else if (thread != xnpod_current_thread() &&	     testbits(thread->status,XNREADY))	/* xnpod_resume_thread() must be called for runnable threads	   but the running one. */	xnpod_resume_thread(thread,0);    else /* In case of a shadow, we do not attempt to renice the	    mated Linux task if we did not renice the former. */	return;#ifdef __KERNEL__    if (testbits(thread->status,XNSHADOW))	xnshadow_renice(thread);#endif /* __KERNEL__ */}/*!  * \fn void xnsynch_sleep_on(xnsynch_t *synch,                             xnticks_t timeout,  			        xnmutex_t *imutex); * \brief Sleep on a synchronization object. * * Makes the calling thread sleep on the specified synchronization * object, waiting for it to be signaled. * * This service should be called by upper interfaces wanting the * current thread to pend on the given resource. * * @param synch The descriptor address of the synchronization object * to sleep on. * * @param timeout The timeout which may be used to limit the time the * thread pends on the resource. This value is a count of ticks. * Passing XN_INFINITE specifies an unbounded wait. All other values * are used to initialize a nanokernel watchdog timer. * * @param imutex The address of an interface mutex currently held by * the caller which will be subject to a lock-breaking preemption * before the current thread is actually switched out. The * corresponding kernel mutex will be automatically reacquired by the * nanokernel when the suspended thread is eventually resumed, before * xnsynch_sleep_on() returns to its caller.  Passing NULL when no * lock breaking is required is valid. See xnpod_schedule() for more * on lock-breaking preemption. * * Side-effect: This routine always calls the rescheduling procedure. * * Context: This routine must be called on behalf of a thread context. */void xnsynch_sleep_on (xnsynch_t *synch,		       xnticks_t timeout,		       xnmutex_t *imutex){    xnthread_t *thread = xnpod_current_thread();    spl_t s;    splhigh(s);    if (testbits(synch->status,XNSYNCH_PRIO))	{	xnthread_t *owner = synch->owner;	insertpqf(&synch->pendq,&thread->plink,thread->cprio);	if (testbits(synch->status,XNSYNCH_PIP) &&	    owner != NULL &&	    xnpod_priocompare(thread->cprio,owner->cprio) > 0)	    {	    if (!testbits(owner->status,XNBOOST))		{		owner->bprio = owner->cprio;		setbits(owner->status,XNBOOST);		}	    if (!testbits(synch->status,XNSYNCH_CLAIMED))		{		insertpqf(&owner->claimq,			  &synch->link,			  getheadpq(&synch->pendq)->prio);		setbits(synch->status,XNSYNCH_CLAIMED);		}	    xnsynch_renice_thread(owner,thread->cprio);	    }	}    else /* otherwise FIFO */	appendpq(&synch->pendq,&thread->plink);    xnpod_suspend_thread(thread,XNPEND,timeout,synch,imutex);    splexit(s);}/*!  * \fn void xnsynch_clear_boost(xnsynch_t *synch, xnthread_t *owner); * \brief Clear the priority boost - INTERNAL. * * This service is called internally whenever a synchronization object * is not claimed anymore by sleepers to reset the object owner's * priority to its initial level. * * @param synch The descriptor address of the synchronization object. * * @param owner The descriptor address of the thread which * currently owns the synchronization object. */static void xnsynch_clear_boost (xnsynch_t *synch,				 xnthread_t *lastowner){    int downprio;    removepq(&lastowner->claimq,&synch->link);    clrbits(synch->status,XNSYNCH_CLAIMED);    downprio = lastowner->bprio;    if (countpq(&lastowner->claimq) == 0)	clrbits(lastowner->status,XNBOOST);    else	{	/* Find the highest priority needed to enforce the PIP. */	int rprio = getheadpq(&lastowner->claimq)->prio;	if (xnpod_priocompare(rprio,downprio) > 0)	    downprio = rprio;	}    if (lastowner->cprio != downprio)	xnsynch_renice_thread(lastowner,downprio);}/*!  * \fn void xnsynch_renice_sleeper(xnthread_t *thread); * \brief Change a sleeper's priority - INTERNAL. * * This service is used by the PIP code to update the pending priority * of a sleeping thread. * * @param thread The descriptor address of the affected thread. */void xnsynch_renice_sleeper (xnthread_t *thread){    xnsynch_t *synch = thread->wchan;    if (testbits(synch->status,XNSYNCH_PRIO))	{	xnthread_t *owner = synch->owner;	removepq(&synch->pendq,&thread->plink);	insertpqf(&synch->pendq,&thread->plink,thread->cprio);	if (testbits(synch->status,XNSYNCH_CLAIMED) &&	    xnpod_priocompare(thread->cprio,owner->cprio) > 0)	    {	    removepq(&owner->claimq,&synch->link);	    insertpqf(&owner->claimq,		      &synch->link,		      thread->cprio);	    xnsynch_renice_thread(owner,thread->cprio);	    }	}}/*!  * \fn void xnsynch_wakeup_one_sleeper(xnsynch_t *synch); * \brief Give the resource ownership to the next waiting thread. *

⌨️ 快捷键说明

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