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

📄 sem.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (spl->owndby == (rt_current = RT_CURRENT)) {		spl->count++;	} else {		if (atomic_cmpxchg(&spl->owndby, 0, rt_current)) {			hard_restore_flags(flags);			return -1;		}		spl->flags = flags;	}	return 0;}/** * @anchor rt_spl_lock_timed * @brief Acquire a spinlock with timeout. * * rt_spl_lock_timed acquires a spinlock @spl, but waiting spinning only  * for an allowed time. * * @param spl must point to an allocated @e SPL structure. * * rt_spl_lock spins on lock till it can be acquired, as for rt_spl_lock, * but only for an allowed time. If the spinlock cannot be acquired in time * the functions returns in error. * This function can be usefull either in itself or as a diagnosis toll * during code development. * * @returns 0 if the spinlock was acquired, -1 if a timeout occured. * */int rt_spl_lock_timed(SPL *spl, unsigned long ns){	unsigned long flags;	RT_TASK *rt_current;	hard_save_flags_and_cli(flags);	if (spl->owndby == (rt_current = RT_CURRENT)) {		spl->count++;	} else {		RTIME end_time;		void *locked;		end_time = rdtsc() + imuldiv(ns, tuned.cpu_freq, 1000000000);		while ((locked = atomic_cmpxchg(&spl->owndby, 0, rt_current)) && rdtsc() < end_time);		if (locked) {			hard_restore_flags(flags);			return -1;		}		spl->flags = flags;	}	return 0;}/** * @anchor rt_spl_unlock * @brief Release an owned spinlock. * * rt_spl_lock releases an owned spinlock @spl. * * @param spl must point to an allocated @e SPL structure. * * rt_spl_unlock releases an owned lock. The spinlock can remain locked and * its ownership can remain with the task is the spinlock acquisition was  * recursed. * * @returns 0 if the function was used legally, -1 if a tasks tries to unlock * a spinlock it does not own. * */int rt_spl_unlock(SPL *spl){	unsigned long flags;	RT_TASK *rt_current;	hard_save_flags_and_cli(flags);	if (spl->owndby == (rt_current = RT_CURRENT)) {		if (spl->count) {			--spl->count;		} else {			spl->owndby = 0;			spl->count  = 0;			hard_restore_flags(spl->flags);		}		return 0;	}	hard_restore_flags(flags);	return -1;}/* ++++++ NAMED SEMAPHORES, BARRIER, COND VARIABLES, RWLOCKS, SPINLOCKS +++++ */#include <rtai_registry.h>/** * @anchor _rt_typed_named_sem_init * @brief Initialize a specifically typed (counting, binary, resource) *	  semaphore identified by a name. * * _rt_typed_named_sem_init allocate and initializes a semaphore identified  * by @e name of type @e type. Once the semaphore structure is allocated the  * initialization is as for rt_typed_sem_init. The function returns the * handle pointing to the allocated semaphore structure, to be used as the * usual semaphore address in all semaphore based services. Named objects * are useful for use among different processes, kernel/user space and * in distributed applications, see netrpc. * * @param sem must point to an allocated SEM structure. * * @param value is the initial value of the semaphore, always set to 1 *	  for a resource semaphore. * * @param type is the semaphore type and queuing policy. It can be an OR * a semaphore kind: CNT_SEM for counting semaphores, BIN_SEM for binary  * semaphores, RES_SEM for resource semaphores; and queuing policy: * FIFO_Q, PRIO_Q for a fifo and priority queueing respectively. * Resource semaphores will enforce a PRIO_Q policy anyhow. *  * Since @a name can be a clumsy identifier, services are provided to * convert 6 characters identifiers to unsigned long, and vice versa. * * @see nam2num() and num2nam(). * * See rt_typed_sem_init for further clues. * * As for all the named initialization functions it must be remarked that * only the very first call to initilize/create a named RTAI object does a  * real allocation of the object, any following call with the same name  * will just increase its usage count. In any case the function returns * a pointer to the named object, or zero if in error. * * @returns either a valid pointer or 0 if in error. * */SEM *_rt_typed_named_sem_init(unsigned long sem_name, int value, int type){	SEM *sem;	if ((sem = rt_get_adr_cnt(sem_name))) {		return sem;	}	if ((sem = rt_malloc(sizeof(SEM)))) {		rt_typed_sem_init(sem, value, type);		if (rt_register(sem_name, sem, IS_SEM, 0)) {			return sem;		}		rt_sem_delete(sem);	}	rt_free(sem);	return (SEM *)0;}/** * @anchor rt_named_sem_delete * @brief Delete a semaphore initialized in named mode. * * rt_named_sem_delete deletes a semaphore previously created with  * @ref _rt_typed_named_sem_init().  * * @param sem points to the structure pointer returned by a corresponding * call to _rt_typed_named_sem_init.  * * Any tasks blocked on this semaphore is returned in error and * allowed to run when semaphore is destroyed.  * As it is done by all the named allocation functions delete calls have just  * the effect of decrementing a usage count till the last is done, as that is  * the one the really frees the object. * * @return an int >=0 is returned upon success, SEM_ERR if it failed to  * delete the semafore, -EFAULT if the semaphore does not exist anymore. * */int rt_named_sem_delete(SEM *sem){	int ret;	if (!(ret = rt_drg_on_adr_cnt(sem))) {		if (!rt_sem_delete(sem)) {			rt_free(sem);			return 0;		} else {			return SEM_ERR;		}	}	return ret;}/** * @anchor _rt_named_rwl_init * @brief Initialize a multi readers single writer lock identified by a name. * * _rt_named_rwl_init allocate and initializes a multi readers single writer  * lock (RWL) identified by @e name. Once the lock structure is allocated the  * initialization is as for rt_rwl_init. The function returns the * handle pointing to the allocated multi readers single writer lock o * structure, to be used as the usual lock address in all rwl based services.  * Named objects are useful for use among different processes, kernel/user  * space and in distributed applications, see netrpc. * * @param rwl must point to an allocated @e RWL structure. * * Since @a name can be a clumsy identifier, services are provided to * convert 6 characters identifiers to unsigned long, and vice versa. * * @see nam2num() and num2nam(). * * As for all the named initialization functions it must be remarked that * only the very first call to initilize/create a named RTAI object does a  * real allocation of the object, any following call with the same name  * will just increase its usage count. In any case the function returns * a pointer to the named object, or zero if in error. * * @returns either a valid pointer or 0 if in error. * */RWL *_rt_named_rwl_init(unsigned long rwl_name){	RWL *rwl;	if ((rwl = rt_get_adr_cnt(rwl_name))) {		return rwl;	}	if ((rwl = rt_malloc(sizeof(RWL)))) {		rt_rwl_init(rwl);		if (rt_register(rwl_name, rwl, IS_RWL, 0)) {			return rwl;		}		rt_rwl_delete(rwl);	}	rt_free(rwl);	return (RWL *)0;}/** * @anchor rt_named_rwl_delete * @brief Delete a multi readers single writer lock in named mode. * * rt_named_rwl_delete deletes a multi readers single writer lock * previously created with @ref rt_named_rwl_init().  * * @param rwl points to the structure pointer returned by a corresponding  * call to rt_named_rwl_init.  * * As it is done by all the named allocation functions delete calls have just  * the effect of decrementing a usage count till the last is done, as that is  * the one the really frees the object. * * @return an int >=0 is returned upon success, SEM_ERR if it failed to  * delete the multi readers single writer lock, -EFAULT if the lock does  * not exist anymore. * */int rt_named_rwl_delete(RWL *rwl){	int ret;	if (!(ret = rt_drg_on_adr_cnt(rwl))) {		if (!rt_rwl_delete(rwl)) {			rt_free(rwl);			return 0;		} else {			return SEM_ERR;		}	}	return ret;}/** * @anchor _rt_named_spl_init * @brief Initialize a spinlock identified by a name. * * _rt_named_spl_init allocate and initializes a spinlock (SPL) identified  * by @e name. Once the spinlock structure is allocated the initialization  * is as for rt_spl_init. The function returns the handle pointing to the  * allocated spinlock structure, to be used as the usual spinlock address  * in all spinlock based services. Named objects are useful for use among  * different processes and kernel/user space. * * @param spl must point to an allocated @e RWL structure. * * Since @a name can be a clumsy identifier, services are provided to * convert 6 characters identifiers to unsigned long, and vice versa. * * @see nam2num() and num2nam(). * * As for all the named initialization functions it must be remarked that * only the very first call to initilize/create a named RTAI object does a  * real allocation of the object, any following call with the same name  * will just increase its usage count. In any case the function returns * a pointer to the named object, or zero if in error. * * @returns either a valid pointer or 0 if in error. * */SPL *_rt_named_spl_init(unsigned long spl_name){	SPL *spl;	if ((spl = rt_get_adr_cnt(spl_name))) {		return spl;	}	if ((spl = rt_malloc(sizeof(SPL)))) {		rt_spl_init(spl);		if (rt_register(spl_name, spl, IS_SPL, 0)) {			return spl;		}		rt_spl_delete(spl);	}	rt_free(spl);	return (SPL *)0;}/** * @anchor rt_named_spl_delete * @brief Delete a spinlock in named mode. * * rt_named_spl_delete deletes a spinlock previously created with * @ref rt_named_spl_init().  * * @param spl points to the structure pointer returned by a corresponding  * call to rt_named_spl_init.  * * As it is done by all the named allocation functions delete calls have just  * the effect of decrementing a usage count till the last is done, as that is  * the one the really frees the object. * * @return an int >=0 is returned upon success, -EFAULT if the spinlock * does not exist anymore. * */int rt_named_spl_delete(SPL *spl){	int ret;	if (!(ret = rt_drg_on_adr_cnt(spl))) {		rt_spl_delete(spl);		rt_free(spl);		return 0;	}	return ret;}/* +++++ SEMAPHORES, BARRIER, COND VARIABLES, RWLOCKS, SPINLOCKS ENTRIES ++++ */struct rt_native_fun_entry rt_sem_entries[] = {	{ { 0, rt_typed_sem_init },        TYPED_SEM_INIT },	{ { 0, rt_sem_delete },            SEM_DELETE },	{ { 0, _rt_typed_named_sem_init }, NAMED_SEM_INIT },	{ { 0, rt_named_sem_delete },      NAMED_SEM_DELETE },	{ { 1, rt_sem_signal },            SEM_SIGNAL },	{ { 1, rt_sem_wait },              SEM_WAIT },	{ { 1, rt_sem_wait_if },           SEM_WAIT_IF },	{ { 1, rt_sem_wait_until },        SEM_WAIT_UNTIL },	{ { 1, rt_sem_wait_timed },        SEM_WAIT_TIMED },	{ { 1, rt_sem_broadcast },         SEM_BROADCAST },	{ { 1, rt_sem_wait_barrier },      SEM_WAIT_BARRIER },	{ { 1, rt_sem_count },             SEM_COUNT },        { { 1, rt_cond_wait },             COND_WAIT },        { { 1, rt_cond_wait_until },       COND_WAIT_UNTIL },        { { 1, rt_cond_wait_timed },       COND_WAIT_TIMED },        { { 0, rt_rwl_init },              RWL_INIT },        { { 0, rt_rwl_delete },            RWL_DELETE },	{ { 0, _rt_named_rwl_init },	   NAMED_RWL_INIT },	{ { 0, rt_named_rwl_delete },      NAMED_RWL_DELETE },        { { 1, rt_rwl_rdlock },            RWL_RDLOCK },        { { 1, rt_rwl_rdlock_if },         RWL_RDLOCK_IF },        { { 1, rt_rwl_rdlock_until },      RWL_RDLOCK_UNTIL },        { { 1, rt_rwl_rdlock_timed },      RWL_RDLOCK_TIMED },        { { 1, rt_rwl_wrlock },            RWL_WRLOCK },        { { 1, rt_rwl_wrlock_if },         RWL_WRLOCK_IF },        { { 1, rt_rwl_wrlock_until },      RWL_WRLOCK_UNTIL },        { { 1, rt_rwl_wrlock_timed },      RWL_WRLOCK_TIMED },        { { 1, rt_rwl_unlock },            RWL_UNLOCK },        { { 0, rt_spl_init },              SPL_INIT },        { { 0, rt_spl_delete },            SPL_DELETE },	{ { 0, _rt_named_spl_init },	   NAMED_SPL_INIT },	{ { 0, rt_named_spl_delete },      NAMED_SPL_DELETE },        { { 1, rt_spl_lock },              SPL_LOCK },        { { 1, rt_spl_lock_if },           SPL_LOCK_IF },        { { 1, rt_spl_lock_timed },        SPL_LOCK_TIMED },        { { 1, rt_spl_unlock },            SPL_UNLOCK },        { { 1, rt_cond_signal}, 	   COND_SIGNAL },	{ { 0, 0 },  		           000 }};extern int set_rt_fun_entries(struct rt_native_fun_entry *entry);extern void reset_rt_fun_entries(struct rt_native_fun_entry *entry);int __rtai_sem_init (void){    return set_rt_fun_entries(rt_sem_entries);}void __rtai_sem_exit (void){    reset_rt_fun_entries(rt_sem_entries);}/* +++++++ END SEMAPHORES, BARRIER, COND VARIABLES, RWLOCKS, SPINLOCKS ++++++ *//*@}*/#ifndef CONFIG_RTAI_SEM_BUILTINmodule_init(__rtai_sem_init);module_exit(__rtai_sem_exit);#endif /* !CONFIG_RTAI_SEM_BUILTIN */#ifdef CONFIG_KBUILDEXPORT_SYMBOL(rt_typed_sem_init);EXPORT_SYMBOL(rt_sem_init);EXPORT_SYMBOL(rt_sem_delete);EXPORT_SYMBOL(rt_sem_count);EXPORT_SYMBOL(rt_sem_signal);EXPORT_SYMBOL(rt_sem_broadcast);EXPORT_SYMBOL(rt_sem_wait);EXPORT_SYMBOL(rt_sem_wait_if);EXPORT_SYMBOL(rt_sem_wait_until);EXPORT_SYMBOL(rt_sem_wait_timed);EXPORT_SYMBOL(rt_sem_wait_barrier);EXPORT_SYMBOL(_rt_typed_named_sem_init);EXPORT_SYMBOL(rt_named_sem_delete);EXPORT_SYMBOL(rt_cond_signal);EXPORT_SYMBOL(rt_cond_wait);EXPORT_SYMBOL(rt_cond_wait_until);EXPORT_SYMBOL(rt_cond_wait_timed);EXPORT_SYMBOL(rt_rwl_init);EXPORT_SYMBOL(rt_rwl_delete);EXPORT_SYMBOL(rt_rwl_rdlock);EXPORT_SYMBOL(rt_rwl_rdlock_if);EXPORT_SYMBOL(rt_rwl_rdlock_until);EXPORT_SYMBOL(rt_rwl_rdlock_timed);EXPORT_SYMBOL(rt_rwl_wrlock);EXPORT_SYMBOL(rt_rwl_wrlock_if);EXPORT_SYMBOL(rt_rwl_wrlock_until);EXPORT_SYMBOL(rt_rwl_wrlock_timed);EXPORT_SYMBOL(rt_rwl_unlock);EXPORT_SYMBOL(_rt_named_rwl_init);EXPORT_SYMBOL(rt_named_rwl_delete);EXPORT_SYMBOL(rt_spl_init);EXPORT_SYMBOL(rt_spl_delete);EXPORT_SYMBOL(rt_spl_lock);EXPORT_SYMBOL(rt_spl_lock_if);EXPORT_SYMBOL(rt_spl_lock_timed);EXPORT_SYMBOL(rt_spl_unlock);EXPORT_SYMBOL(_rt_named_spl_init);EXPORT_SYMBOL(rt_named_spl_delete);#endif /* CONFIG_KBUILD */

⌨️ 快捷键说明

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