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

📄 sem.c

📁 rtai-3.1-test3的源代码(Real-Time Application Interface )
💻 C
📖 第 1 页 / 共 4 页
字号:
int rt_cond_wait_timed(CND *cnd, SEM *mtx, RTIME delay){	return rt_cond_wait_until(cnd, mtx, get_time() + delay);}/* ++++++++++++++++++++ READERS-WRITER LOCKS SUPPORT ++++++++++++++++++++++++ *//** * @anchor rt_rwl_init * @brief Initialize a multi readers single writer lock. * * rt_rwl_init initializes a multi readers single writer lock @rwl. * * @param rwl must point to an allocated @e RWL structure. * * A multi readers single writer lock (RWL) is a synchronization mechanism  * that allows to have simultaneous read only access to an object, while only  * one task can have write access. A data set which is searched more  * frequently than it is changed can be usefully controlled by using an rwl.  * The lock acquisition policy is determined solely on the priority of tasks  * applying to own a lock. * * @returns 0 if always. * */int rt_rwl_init(RWL *rwl){	rt_typed_sem_init(&rwl->wrmtx, 1, RES_SEM);	rt_typed_sem_init(&rwl->wrsem, 0, CNT_SEM);	rt_typed_sem_init(&rwl->rdsem, 0, CNT_SEM);	return 0;}/** * @anchor rt_rwl_delete * @brief destroys a multi readers single writer lock. * * rt_rwl_init destroys a multi readers single writer lock @rwl. * * @param rwl must point to an allocated @e RWL structure. * * @returns 0 if OK, SEM_ERR if anything went wrong. * */int rt_rwl_delete(RWL *rwl){	int ret;	ret  =  rt_sem_delete(&rwl->rdsem);	ret |= !rt_sem_delete(&rwl->wrsem);	ret |= !rt_sem_delete(&rwl->wrmtx);	return ret ? 0 : SEM_ERR;}/** * @anchor rt_rwl_rdlock * @brief acquires a multi readers single writer lock for reading. * * rt_rwl_rdlock acquires a multi readers single writer lock @rwl for * reading. The calling task will block only if any writer owns the lock * already or there are writers with higher priority waiting to acquire  * write access. * * @param rwl must point to an allocated @e RWL structure. * * @returns 0 if OK, SEM_ERR if anything went wrong after being blocked. * */int rt_rwl_rdlock(RWL *rwl){	unsigned long flags;	RT_TASK *wtask, *rt_current;	flags = rt_global_save_flags_and_cli();	rt_current = RT_CURRENT;	while (rwl->wrmtx.owndby || ((wtask = (rwl->wrsem.queue.next)->task) && wtask->priority <= rt_current->priority)) {		int ret;		if (rwl->wrmtx.owndby == rt_current) {			rt_global_restore_flags(flags);			return SEM_ERR + 1;		}		if ((ret = rt_sem_wait(&rwl->rdsem)) >= SEM_TIMOUT) {			rt_global_restore_flags(flags);			return ret;		}	}	((int *)&rwl->rdsem.owndby)[0]++;	rt_global_restore_flags(flags);	return 0;}/** * @anchor rt_rwl_rdlock_if * @brief try to acquire a multi readers single writer lock just for reading. * * rt_rwl_rdlock_if tries to acquire a multi readers single writer lock @rwl  * for reading immediately, i.e. without blocking if a writer owns the lock * or there are writers with higher priority waiting to acquire write access. * * @param rwl must point to an allocated @e RWL structure. * * @returns 0 if the lock was acquired, -1 if the lock was already owned. * */int rt_rwl_rdlock_if(RWL *rwl){	unsigned long flags;	RT_TASK *wtask;	flags = rt_global_save_flags_and_cli();	if (!rwl->wrmtx.owndby && (!(wtask = (rwl->wrsem.queue.next)->task) || wtask->priority > RT_CURRENT->priority)) {		((int *)&rwl->rdsem.owndby)[0]++;		rt_global_restore_flags(flags);		return 0;	}	rt_global_restore_flags(flags);	return -1;}/** * @anchor rt_rwl_rdlock_until * @brief try to acquire a multi readers single writer lock for reading within * an absolute deadline time. * * rt_rwl_rdlock_untill tries to acquire a multi readers single writer lock  * @rwl for reading, as for rt_rwl_rdlock, but timing out if the lock has not  * been acquired within an assigned deadline. * * @param rwl must point to an allocated @e RWL structure. * * @time is the time deadline, in internal count units. * * @returns 0 if the lock was acquired, SEM_TIMOUT if the deadline expired * without acquiring the lock, SEM_ERR in case something went wrong. * */int rt_rwl_rdlock_until(RWL *rwl, RTIME time){	unsigned long flags;	RT_TASK *wtask, *rt_current;	flags = rt_global_save_flags_and_cli();	rt_current = RT_CURRENT;	while (rwl->wrmtx.owndby || ((wtask = (rwl->wrsem.queue.next)->task) && wtask->priority <= rt_current->priority)) {		int ret;		if (rwl->wrmtx.owndby == rt_current) {			rt_global_restore_flags(flags);			return SEM_ERR + 1;		}		if ((ret = rt_sem_wait_until(&rwl->rdsem, time)) >= SEM_TIMOUT) {			rt_global_restore_flags(flags);			return ret;		}	}	((int *)&rwl->rdsem.owndby)[0]++;	rt_global_restore_flags(flags);	return 0;}/** * @anchor rt_rwl_rdlock_timed * @brief try to acquire a multi readers single writer lock for reading within * a relative deadline time. * * rt_rwl_rdlock_timed tries to acquire a multi readers single writer lock @rwl  * for reading, as for rt_rwl_rdlock, but timing out if the lock has not been  * acquired within an assigned deadline. * * @param rwl must point to an allocated @e RWL structure. * * @delay is the time delay within which the lock must be acquired, in  * internal count units. * * @returns 0 if the lock was acquired, SEM_TIMOUT if the deadline expired * without acquiring the lock, SEM_ERR in case something went wrong. * */int rt_rwl_rdlock_timed(RWL *rwl, RTIME delay){	return rt_rwl_rdlock_until(rwl, get_time() + delay);}/** * @anchor rt_rwl_wrlock * @brief acquires a multi readers single writer lock for wrtiting. * * rt_rwl_rwlock acquires a multi readers single writer lock @rwl for * writing. The calling task will block if any other task, reader or writer,  * owns the lock already. * * @param rwl must point to an allocated @e RWL structure. * * @returns 0 if OK, SEM_ERR if anything went wrong after being blocked. * */int rt_rwl_wrlock(RWL *rwl){	unsigned long flags;	int ret;	flags = rt_global_save_flags_and_cli();	while (rwl->rdsem.owndby) {		if ((ret = rt_sem_wait(&rwl->wrsem)) >= SEM_TIMOUT) {			rt_global_restore_flags(flags);			return ret;		}	}	if ((ret = rt_sem_wait(&rwl->wrmtx)) >= SEM_TIMOUT) {		rt_global_restore_flags(flags);		return ret;	}	rt_global_restore_flags(flags);	return 0;}/** * @anchor rt_rwl_wrlock_if * @brief acquires a multi readers single writer lock for writing. * * rt_rwl_wrlock_if try to acquire a multi readers single writer lock @rwl  * for writing immediately, i.e without blocking if the lock is owned already. * * @param rwl must point to an allocated @e RWL structure. * * @returns 0 if the lock was acquired, -1 if the lock was already owned. * */int rt_rwl_wrlock_if(RWL *rwl){	unsigned long flags;	flags = rt_global_save_flags_and_cli();	if (!rwl->rdsem.owndby && rt_sem_wait_if(&rwl->wrmtx) >= 0) {		rt_global_restore_flags(flags);		return 0;	}	rt_global_restore_flags(flags);	return -1;}/** * @anchor rt_rwl_wrlock_until * @brief try to acquire a multi readers single writer lock for writing within * an absolute deadline time. * * rt_rwl_rwlock_until tries to acquire a multi readers single writer lock  * @rwl for writing, as for rt_rwl_rwlock, but timing out if the lock has not  * been acquired within an assigned deadline. * * @param rwl must point to an allocated @e RWL structure. * * @time is the time deadline, in internal count units. * * @returns 0 if the lock was acquired, SEM_TIMOUT if the deadline expired * without acquiring the lock, SEM_ERR in case something went wrong. * */int rt_rwl_wrlock_until(RWL *rwl, RTIME time){	unsigned long flags;	int ret;	flags = rt_global_save_flags_and_cli();	while (rwl->rdsem.owndby) {		if ((ret = rt_sem_wait_until(&rwl->wrsem, time)) >= SEM_TIMOUT) {			rt_global_restore_flags(flags);			return ret;		};	}	if ((ret = rt_sem_wait_until(&rwl->wrmtx, time)) >= SEM_TIMOUT) {		rt_global_restore_flags(flags);		return ret;	};	rt_global_restore_flags(flags);	return 0;}/** * @anchor rt_rwl_wrlock_timed * @brief try to acquire a multi readers single writer lock for writing within * a relative deadline time. * * rt_rwl_wrlock_timed tries to acquire a multi readers single writer lock @rwl  * for writing, as for rt_rwl_wrlock, timing out if the lock has not been  * acquired within an assigned deadline. * * @param rwl must point to an allocated @e RWL structure. * * @delay is the time delay within which the lock must be acquired, in  * internal count units. * * @returns 0 if the lock was acquired, SEM_TIMOUT if the deadline expired * without acquiring the lock, SEM_ERR in case something went wrong. * */int rt_rwl_wrlock_timed(RWL *rwl, RTIME delay){	return rt_rwl_wrlock_until(rwl, get_time() + delay);}/** * @anchor rt_rwl_unlock * @brief unlock an acquired multi readers single writer lock. * * rt_rwl_unlock unlocks an acquired multi readers single writer lock @rwl.  * After releasing the lock any task waiting to acquire it will own the lock * according to its priority, whether it is a reader or a writer, otherwise * the lock will be fully unlocked. * * @param rwl must point to an allocated @e RWL structure. * * @returns 0 always. * */int rt_rwl_unlock(RWL *rwl){	unsigned long flags;	flags = rt_global_save_flags_and_cli();	if (rwl->wrmtx.owndby) {		rt_sem_signal(&rwl->wrmtx);	} else if (rwl->rdsem.owndby) {	           rwl->rdsem.owndby = (struct rt_task_struct *)((char *)rwl->rdsem.owndby - 1);	}	rt_global_restore_flags(flags);	flags = rt_global_save_flags_and_cli();	if (!rwl->wrmtx.owndby && !rwl->rdsem.owndby) {		RT_TASK *wtask, *rtask;		wtask = (rwl->wrsem.queue.next)->task;		rtask = (rwl->rdsem.queue.next)->task;		if (wtask && rtask) {			if (wtask->priority < rtask->priority) {				rt_sem_signal(&rwl->wrsem);			} else {				rt_sem_signal(&rwl->rdsem);			}		} else if (wtask) {			rt_sem_signal(&rwl->wrsem);		} else if (rtask) {			rt_sem_signal(&rwl->rdsem);		}        }	rt_global_restore_flags(flags);	return 0;}/* +++++++++++++++++++++ RECURSIVE SPINLOCKS SUPPORT ++++++++++++++++++++++++ *//** * @anchor rt_spl_init * @brief Initialize a spinlock. * * rt_spl_init initializes a spinlock @spl. * * @param spl must point to an allocated @e SPL structure. * * A spinlock is an active wait synchronization mechanism useful for multi * processors very short synchronization, when it is more efficient to wait * at a meeting point instead of being suspended and the reactivated, as by * using semaphores, to acquire ownership of any object. * Spinlocks can be recursed once acquired, a recurring owner must care of * unlocking as many times as he took the spinlock. * * @returns 0 if always. * */int rt_spl_init(SPL *spl){	spl->owndby = 0;	spl->count  = 0;	return 0;}/** * @anchor rt_spl_delete * @brief Initialize a spinlock. * * rt_spl_delete destroies a spinlock @spl. * * @param spl must point to an allocated @e SPL structure. * * @returns 0 if always. * */int rt_spl_delete(SPL *spl){        return 0;}/** * @anchor rt_spl_lock * @brief Acquire a spinlock. * * rt_spl_lock acquires a spinlock @spl. * * @param spl must point to an allocated @e SPL structure. * * rt_spl_lock spins on lock till it can be acquired. If a tasks asks for * lock it owns already it will acquire it immediately but will have to care * to unlock it as many times as it recursed the spinlock ownership. * * @returns 0 if always. * */int rt_spl_lock(SPL *spl){	unsigned long flags;	RT_TASK *rt_current;	hard_save_flags_and_cli(flags);	if (spl->owndby == (rt_current = RT_CURRENT)) {		spl->count++;	} else {		while (atomic_cmpxchg(&spl->owndby, 0, rt_current));		spl->flags = flags;	}	return 0;}/** * @anchor rt_spl_lock_if * @brief Acquire a spinlock without waiting. * * rt_spl_lock_if acquires a spinlock @spl without waiting. * * @param spl must point to an allocated @e SPL structure. * * rt_spl_lock_if tries to acquire a spinlock but will not spin on it if * it is owned already. * * @returns 0 if it succeeded, -1 if the lock was owned already. * */int rt_spl_lock_if(SPL *spl){	unsigned long flags;	RT_TASK *rt_current;	hard_save_flags_and_cli(flags);

⌨️ 快捷键说明

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