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

📄 rzkacquiresemaphore.c

📁 zilog的实时操作系统RZK,可以移植到多种处理器上
💻 C
字号:
/*
* File			:	RZKAcquireSemaphore.c
*
* Description	:	This file contains the RZKAcquireSemaphore function that 
*					acquires a given semaphore.
* 
* Copyright 2004 ZiLOG Inc.  ALL RIGHTS RESERVED.
*
* This file contains unpublished confidential and proprietary information
* of ZiLOG, Inc.
* NO PART OF THIS WORK MAY BE DUPLICATED, STORED, PUBLISHED OR DISCLOSED 
* IN ANY FORM WITHOUT THE PRIOR WRITTEN CONSENT OF ZiLOG, INC.
* This is not a license and no use of any kind of this work is authorized
* in the absence of a written license granted by ZiLOG, Inc. in ZiLOG's 
* sole discretion 
*/


#include "ZSysgen.h"
#include "ZTypes.h"
#include "ZThread.h"
#include "ZQueue.h"
#include "ZSemaphore.h"
#include "ZScheduler.h"
#include "ZInterrupt.h"

//extern UINT var2[];
extern UINT8 uNestedISRCount;   
#define pCurrentThread ((RZK_TCB_t *) hCurrentThread)
#define pSemaphore ((RZK_SEMAPHORE_t *) hSemaphore)

/** extern functions */
//extern void RZKScheduler();
extern void AddToOwnerQueue(RZK_HANDLE_t hThread,RZK_SEMAPHORE_t* hSemaphore);
extern void AppendToResourceQueue(RZK_HANDLE_t hObject,RZK_THREADHANDLE_t hThread);
extern void WaitOnResourceQueue( RZK_HANDLE_t hControlBlock,UINT16 uBlockingReason,
							TICK_t tBlockTime);
extern void UpdatePriorityRecursive( RZK_HANDLE_t hThread  );

/** extern variables */
extern RZK_THREADHANDLE_t hCurrentThread;



/*
* Function		:	RZKAcquireSemaphore
*
* Description	:	Will acquire a semaphore only if 
*					the calling thread can decrement the counter associated with the
*					semaphore without letting it go negative. The 
*					thread does a timed wait if semaphore is not 
*					immediately available. 
* 
* Inputs		:	hSemaphore - This is the handle to the semaphore.
*						
*					tBlockTime - Specifies the time of block.	
*
* Outputs		:	RZKERR_SUCCESS - If the semaphore was successfully acquired
*					RZKERR_CB_BUSY - If the semaphore control block is being used exclusively by other thread.
*					RZKERR_INVALID_HANDLE - If the handle to the semaphore is invalid.
*					RZKERR_TIMEOUT - If the tBlocktime is 0 after checking if uDynamicCount is equal to 0
*					RZKERR_OBJECT_DELETED - If the semaphore is deleted
*					RZKERR_OBJECT_RESET - If the semaphore is reset
*
* Dependencies	:	All externs
*/


RZK_STATUS_t RZKAcquireSemaphore
								( 
									RZK_SEMAPHOREHANDLE_t hSemaphore,
									TICK_t tBlockTime
								)

{
	/* Local Variables */
//	RZK_TCB_t *pInsert;
	RZK_STATUS_t err;
	RZK_STATE_t uState;

	/* Validate the handle */
#ifdef RZK_DEBUG
	if((pSemaphore == NULL)||(pSemaphore -> uState == 0)||
	(pSemaphore -> magic_num != MAGIC_NUM_SEMAPHORE))
		return RZKERR_INVALID_HANDLE;
#endif

#ifndef RZK_PERFORMANCE
	if(!(pSemaphore -> uState & OBJECT_CREATED))
		return RZKERR_CB_BUSY;
#endif

#ifdef RZK_PRIORITYINHERITANCE

    if( (pSemaphore->uState & OBJECT_PRIORITY_INHERITANCE) && 
        (uNestedISRCount != 0) )
        return RZKERR_INVALID_OPERATION;

#endif

	uState = RZKDisablePreemption();
	if(pSemaphore -> uDynamicCount != 0)
	{
		--pSemaphore -> uDynamicCount;
		#ifdef RZK_PRIORITYINHERITANCE
			pSemaphore->pOwnerThread = pCurrentThread;		
			/* Add the semaphore to the owner thread owned resources list*/
			if(pSemaphore->uState & OBJECT_PRIORITY_INHERITANCE)
				AddToOwnerQueue(hCurrentThread,pSemaphore);
		#endif /* end of RZK_PRIORITYINHERITANCE */
		RZKRestorePreemption(uState);
		pCurrentThread->errNum = RZKERR_SUCCESS;
		return RZKERR_SUCCESS;
	}
	else
	{
		if(tBlockTime == 0)
		{
			RZKRestorePreemption(uState);
			pCurrentThread->errNum = RZKERR_TIMEOUT;
			return RZKERR_TIMEOUT;
		}
		else
		{
			/* Add to resource queue */
			AppendToResourceQueue(pSemaphore,hCurrentThread);
			WaitOnResourceQueue(pSemaphore,BLOCK_ACQUIRESEMAPHORE,tBlockTime);	

			#ifdef RZK_PRIORITYINHERITANCE
				/* Update the priority of the owner of the semaphore on which current thread is blocked */
				if((pSemaphore->uState & OBJECT_PRIORITY_INHERITANCE) && (pSemaphore-> pResNext == pCurrentThread))
				{
					/* updates both the inherited and dispatch priority recursively */
					UpdatePriorityRecursive(hCurrentThread);
				}
			#endif /* end of RZK_PRIORITYINHERITANCE */

			pCurrentThread->errNum = RZKERR_SUCCESS;
			/* Reset the running bit in the TCB */
			pCurrentThread -> uState &= ~(THREAD_RUNNING);
		}/*tBlockTime != 0 */
	} /* End of else statement for uDynamicCount = 0 */
	RZKRestorePreemption(uState);
	err = pCurrentThread->errNum;
	return(err);
} /* End of RZKAcquireSemaphore */

⌨️ 快捷键说明

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