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

📄 semaphor.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
			RETAILMSG( 1, ( "KL_LeaveCriticalSection error: the thread( handle(0x%x), id(0x%x), curproc=%s, ownerproc=%s )is not own CriticalSection.\r\n", lpCurThread->hThread, lpCurThread->dwThreadId, lpCurThread->lpCurProcess->lpszApplicationName, lpCurThread->lpOwnerProcess->lpszApplicationName ) );
			DumpCallStack( lpCurThread );			
		}
	}
	else
	{
		ERRORMSG( 1 , ( "KL_LeaveCriticalSection error: null ptr,pc=0x%x,id=0x%x,curproc=%s, ownerproc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->dwThreadId, lpCurThread->lpCurProcess->lpszApplicationName, lpCurThread->lpOwnerProcess->lpszApplicationName ) );
		DumpCallStack( lpCurThread );		
	}
}

// ********************************************************************
// 声明:DoEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection, BOOL bEntryBlock )
// 参数:
//		IN lpCriticalSection - CRITICAL_SECTION结构指针
//		IN bEntryBlock - 当不拥有冲突段时,是否退出
// 返回值:
//		当拥有冲突段,返回TRUE; 否则,返回FALSE
// 功能描述:
//		进入冲突段,不管是否拥有,都回退出
// 引用:
//		系统API
// ********************************************************************

static BOOL DoEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection, BOOL bEntryBlock )
{
	BOOL bRetv = FALSE;
	if( lpCriticalSection )
	{
		if( lpCriticalSection->dwOwnerThreadId == lpCurThread->dwThreadId )		//当前线程拥有该冲突段吗?
		{	//是,简单的将计数器加一
			lpCriticalSection->iLockCount++;
			bRetv = TRUE;
			
#ifdef __DEBUG
			if( lpCriticalSection->uiFlag & CSF_DEBUG )
			{
				RETAILMSG( 1, ( "EnterCriticalSection skip:lpcs=0x%x,lpcsName=%s,iLockCount=%d.\r\n", lpCriticalSection, lpCriticalSection->lpcsName, lpCriticalSection->iLockCount ) );
			}
#endif
		}
		else
		{	// 不拥有,否
			LPSEMAPHORE lpho;
			
#ifdef __DEBUG
			if( lpCriticalSection->uiFlag & CSF_DEBUG )
			{
				RETAILMSG( 1, ( "CS-wait...:lpcs=0x%x,lpcsName=%s,Owner Thread=0x%x.\r\n", lpCriticalSection, lpCriticalSection->lpcsName, lpCriticalSection->dwOwnerThreadId ) );
			}
#endif
			
#ifdef DEBUG_CRITSEC
			
			if( lpCriticalSection->lpcsName ) 
			{
				DWORD dwCurThreadId = KL_GetCurrentThreadId();
				RETAILMSG( 1, ( "downcs-enter=%s, cid=0x%x, oid=0x%x, count=%d\r\n", lpCriticalSection->lpcsName, dwCurThreadId, lpCriticalSection->dwOwnerThreadId, lpCriticalSection->iLockCount ) );
			}
#endif	
			
			if( lpCriticalSection->uiFlag & CSF_KERNEL )//是否是内核自己的创建的
				lpho = (LPSEMAPHORE)lpCriticalSection->hSemaphore; //是
			else
				lpho = (LPSEMAPHORE)HandleToPtr( lpCriticalSection->hSemaphore, -1 ); // 否,用户对象
			lpho = GetSemaphoreAndLock( lpho, 0 );
			if( lpho )
			{			
				bRetv = DownCrit( lpho, lpCriticalSection, bEntryBlock );	//进入原子操作
				ReleaseSemaphoreAndUnlock( lpho );			
			}
			else
			{
				ERRORMSG( 1 , ( "KL_EnterCriticalSection error: null lpho,id=0x%x,pc=0x%x,proc=%s.\r\n", lpCurThread->dwThreadId, lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
				DumpCallStack( lpCurThread );
			}
			
#ifdef DEBUG_CRITSEC
			if( lpCriticalSection->lpcsName ) 
			{
				DWORD dwCurThreadId = KL_GetCurrentThreadId();
				RETAILMSG( 1, ( "downcs-exit=%s, cid=0x%x, oid=0x%x, count=%d\r\n", lpCriticalSection->lpcsName, dwCurThreadId, lpCriticalSection->dwOwnerThreadId, lpCriticalSection->iLockCount ) );
			}
#endif
		}
	}
	else
	{
		ERRORMSG( 1 , ( "KL_EnterCriticalSection error: null ptr,pc=0x%x,proc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
		DumpCallStack( lpCurThread );		
	}
	return bRetv;
}

// ********************************************************************
// 声明:VOID WINAPI KL_EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
//		IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
//		无
// 功能描述:
//		进入冲突段
// 引用:
//		系统API
// ********************************************************************

VOID WINAPI KL_EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
	DoEnterCriticalSection( lpCriticalSection, TRUE );
}

// ********************************************************************
// 声明:BOOL WINAPI KL_TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
//		IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
//		当拥有冲突段,返回TRUE; 否则,返回FALSE
// 功能描述:
//		进入冲突段,不管是否拥有,都回退出
// 引用:
//		系统API
// ********************************************************************

BOOL WINAPI KL_TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
	return DoEnterCriticalSection( lpCriticalSection, FALSE );
}


// ********************************************************************
// 声明:static LPVOID GetThreadSemp( LPTHREAD lpThread )
// 参数:
//		IN lpThread - THREAD线程结构指针
// 返回值:
//		信号量对象
// 功能描述:
//		得到线程的信号量
// 引用:
//	
// ********************************************************************


static LPVOID GetThreadSemp( LPTHREAD lpThread )
{
	return lpThread->lpsemExit;
}

// ********************************************************************
// 声明:LPSEMAPHORE GetSemaphoreAndLock( HANDLE hSem )
// 参数:
//		IN hSem - 信号量句柄
//		IN uObjType - 对象类型
// 返回值:
//		信号量对象指针
// 功能描述:
//		得到信号量句柄对应的指针并且锁住它
// 引用:
//	
// ********************************************************************

#define DEBUG_GetSemaphoreAndLock 0
LPSEMAPHORE GetSemaphoreAndLock( HANDLE hSem, UINT uObjType )
{
    LPSEMAPHORE lpSem;
	UINT uiSave;

	LockIRQSave( &uiSave );

	if( uObjType )
	    lpSem = HandleToPtr( hSem, uObjType );//由句柄得到对象指针
	else
		lpSem = (LPSEMAPHORE)hSem;

	if( lpSem ) 
	{
		if( lpSem->nRefCount )
		    lpSem->nRefCount++;
		else
		{
			lpSem = NULL;  //已经被释放!			
		}
	}

    UnlockIRQRestore( &uiSave );

#ifdef __DEBUG
	if( lpSem == NULL )
	{
		WARNMSG( DEBUG_GetSemaphoreAndLock, ( "GetSemaphoreAndLock been released or invalid handle!.\r\n" ) );
	}
#endif

	return lpSem;
}

// ********************************************************************
// 声明:LPSEMAPHORE ReleaseSemaphoreAndUnlock( HANDLE hSem, UINT uObjType )
// 参数:
//		IN hSem - 信号量句柄
//		IN uObjType - 对象类型
// 返回值:
//		信号量对象指针
// 功能描述:
//		得到信号量句柄对应的指针并且锁住它
// 引用:
//	
// ********************************************************************

#define DEBUG_ReleaseSemaphoreAndUnlock 0

VOID ReleaseSemaphoreAndUnlock( LPSEMAPHORE lpSem )
{
	UINT uiSave;

	LockIRQSave( &uiSave );

	if( lpSem ) 
	{	
		ASSERT( lpSem->nRefCount > 0 );
		if( lpSem->nRefCount == 1 )
		{
			lpSem->nRefCount = 0;
			UnlockIRQRestore( &uiSave );
			
			_SemaphoreDelete( lpSem );
			
			WARNMSG( DEBUG_ReleaseSemaphoreAndUnlock, ( "ReleaseSemaphoreAndUnlock: not free semaphore.\r\n" ) );
			return;
		}
		else
		{
			lpSem->nRefCount--;
			DEBUGMSG( DEBUG_ReleaseSemaphoreAndUnlock, ( "ReleaseSemaphoreAndUnlock: refcount(%d)!.\r\n",lpSem->nRefCount ) );
		}
	}
	else
	{
		ERRORMSG( DEBUG_ReleaseSemaphoreAndUnlock, ( "ReleaseSemaphoreAndUnlock: not know error!.\r\n" ) );
	}


    UnlockIRQRestore( &uiSave );
}


// ********************************************************************
// 声明:DWORD WINAPI KL_WaitForSingleObject( HANDLE handle, DWORD dwMilliseconds )
// 参数:
//		IN handle - 对象句柄
//		IN dwMilliseconds - 等待时间,假如为INFINITE则为死等
// 返回值:
//		WAIT_OBJECT_0 - 等待的对象有信号
//		WAIT_TIMEOUT - 等待的对象无信号,超时退出
//		WAIT_FAILED - 错误退出
// 功能描述:
//		等待一个对象直到其有信号或超时
// 引用:
//		系统API
// ********************************************************************

#define DEBUG_KL_WaitForSingleObject 0
DWORD WINAPI KL_WaitForSingleObject( HANDLE handle, DWORD dwMilliseconds )
{
	UINT objType;
	DWORD dwRetv = WAIT_FAILED;
	LPSEMAPHORE lpho;

	if( handle == CURRENT_THREAD_HANDLE || 
		handle == CURRENT_PROCESS_HANDLE  )
		goto _error;	

	objType = GetHandleObjType( handle );	//得到对象类型
	if( objType == OBJ_PROCESS )
	{
		LPPROCESS lpProcess = (LPPROCESS)HandleToPtr( handle, OBJ_PROCESS );
		if( lpProcess )
		{	//主进程
			handle = lpProcess->lpMainThread->hThread;
			objType = OBJ_THREAD;
		}
		else
		{
			goto _error;
		}
	}
    switch( objType )
    { 
	case OBJ_EVENT:
    case OBJ_SEMAPHORE:
    case OBJ_MUTEX:
		{
			lpho = GetSemaphoreAndLock( handle, objType );//HandleToPtr( handle, objType );//由句柄得到对象指针
			if( lpho )
			{   
			   //*lppSem = lpho;	
				// 进入原子操作
			    dwRetv = DownSemphores( &lpho, 1, dwMilliseconds, TRUE );
				ReleaseSemaphoreAndUnlock( lpho );
			}
		}
		break;
	case OBJ_THREAD:
		{
			LPTHREAD lpThread = (LPTHREAD)HandleToPtr( handle, OBJ_THREAD );

			if( lpThread )
			{				
				lpho = GetThreadSemp( lpThread );	//得到线程的退出信号对象				
				lpho = GetSemaphoreAndLock( lpho, 0 );
				if( lpho )
				{
					//*lppSem = lpho;
					//	原子操作
					dwRetv = DownSemphores( &lpho, 1, dwMilliseconds, TRUE );
					ReleaseSemaphoreAndUnlock( lpho );
				}
				
			}
			else
				dwRetv = WAIT_OBJECT_0;
		}
		break;
    default:
        ASSERT_NOTIFY( 0, "Invalid semaphore handle.\r\n" );
    }
_error:
	KL_SetLastError( ERROR_INVALID_PARAMETER );
	return dwRetv;
}

// ********************************************************************
// 声明:DWORD WINAPI KL_WaitForMultipleObjects(
//							 DWORD nCount, 
//							 CONST HANDLE *lpHandles, 
//							 BOOL fWaitAll, 
//							 DWORD dwMilliseconds )
// 参数:
//		IN nCount - 信号对象的数量
//		IN lpHandles - 保存有信号对象的句柄数组
//		IN fWaitAll - 是否等待所有对象有信号才返回
//		IN dwMilliseconds - 是否用超时返回功能,当值为INFINITE,表示没有超时功能;
//			否则,当等待时间达到dwMilliseconds所标定的值但仍没有信号产生时,
//			该函数将退出并返回WAIT_TIMEOUT
// 返回值:
//		返回WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount –1) 标示那一个对象有信号;
//		返回WAIT_TIMEOUT - 说明一个超时返回,当dwMilliseconds有效时才会返回该值
//		返回WAIT_FAILED - 系统产生一个错误
// 功能描述:
//		根据条件,等待一个或多个对象直到它们有信号或超时
// 引用:
//	
// ********************************************************************

DWORD WINAPI KL_WaitForMultipleObjects(
							 DWORD nCount, 
							 CONST HANDLE *lpHandles, 
							 BOOL fWaitAll, 
							 DWORD dwMilliseconds )
{
    DWORD i = 0;
	DWORD dwRetv = WAIT_FAILED;
//	UINT uiSave;
	LPSEMAPHORE lppSem[MAX_WAITOBJS];  //最大32个

	if( nCount > MAX_WAITOBJS )
	{   //参数无效
		KL_SetLastError( ERROR_INVALID_PARAMETER );
		return WAIT_FAILED;
	}
	//每个信号量指针指向对应的信号量
	for( i = 0; i < nCount; i++ )
	{
		UINT objType;
		
		if( lpHandles[i] == CURRENT_THREAD_HANDLE || 
			lpHandles[i] == CURRENT_PROCESS_HANDLE  )
			break;
		
		objType = GetHandleObjType( lpHandles[i] );
		
		if( objType == OBJ_EVENT ||
			objType == OBJ_SEMAPHORE ||
			objType == OBJ_MUTEX )
		{
			if( ( lppSem[i] = GetSemaphoreAndLock( lpHandles[i], objType ) ) == NULL )
				break;
		}
		else if( objType == OBJ_THREAD || objType == OBJ_PROCESS )
		{
			LPTHREAD lpThread;
			HANDLE h = lpHandles[i];
			
			if( objType == OBJ_PROCESS )
			{
				LPPROCESS lpProcess;
				
				lpProcess = HandleToPtr( h, OBJ_PROCESS );
				if( lpProcess )
					h = lpProcess->lpMainThread->hThread;
				else
					h = 0;
			}
			
			lpThread = (LPTHREAD)HandleToPtr( h, OBJ_THREAD );
			if( lpThread )
			{
				LPSEMAPHORE lpSem;
				if( ( lpSem = GetThreadSemp( lpThread ) ) == NULL )
				{   //无效
					break;
				}
				//是否锁住?
				if( (lppSem[i] = GetSemaphoreAndLock( lpSem, 0 )) == NULL )
					break;
			}
			else
			{  // thread 已经死掉
				if( fWaitAll == FALSE || nCount == 1 )
				{
					dwRetv = WAIT_OBJECT_0 + i;
					break;
				}
				else
				{	//失败
					break;// 将来增加
				}
			}
		}
		else
			break;
	}
	//
	if( i == nCount )
	{	// 所有对象有效,进入原子操作
		dwRetv = DownSemphores( lppSem, nCount, dwMilliseconds, fWaitAll );
	}
	else
	{
		RETAILMSG( 1, ( "WaitForMultipleObjects error: not all wait objects are valid.\r\n" ) );
	}


	//清除
	nCount = i;
	for( i = 0; i < nCount; i++ )
	{
		ReleaseSemaphoreAndUnlock( lppSem[i] );
	}

	return dwRetv;
}


⌨️ 快捷键说明

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