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

📄 semaphor.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 3 页
字号:
//	IN lpName-以字符串表示的对象名

// 返回值:
//	成功:返回信号量句柄
//	否则:返回NULL
// 功能描述:
//	创建一个信号量	
// 引用:
//	
// ********************************************************************

HANDLE WINAPI KL_CreateSemaphore(
                   LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,  //
                   int nInitialCount,                         // initial count
                   int nMaximumCount,                     // maximum count
                   LPCTSTR lpName     //
                   )
{
    return _CreateHandleObj( lpSemaphoreAttributes, nInitialCount, nMaximumCount, lpName, SF_SEMAPHORE, OBJ_SEMAPHORE, GetAPICallerProcessPtr() );
}

// ********************************************************************
// 声明:BOOL WINAPI KL_ReleaseSemaphore(
//					   HANDLE hSemaphore,
//					   int lReleaseCount,       //
//					   LPINT lpPreviousCount   // 
//					   )

// 参数:
//	IN hSemaphore-信号量句柄
//	IN lReleaseCount-释放计数
//	OUT lpPreviousCount-用于接受前次信号量计数

// 返回值:
//	成功:返回非零
//	否则:返回0
	
// 功能描述:
//	释放信号,假如有线程在等待该信号量则释放这些线程
// 引用:
//	系统API
// ********************************************************************

BOOL WINAPI KL_ReleaseSemaphore(
					   HANDLE hSemaphore,
					   int lReleaseCount,       //
					   LPINT lpPreviousCount   //
					   )
{
    LPSEMAPHORE lpho = HandleToPtr( hSemaphore, OBJ_SEMAPHORE ); // 由句柄得到对象指针
	
	if( lpPreviousCount )
		*lpPreviousCount = 0;

    if( lpho )
    {
		return _SemaphoreRelease( lpho, lReleaseCount, lpPreviousCount );
    }
    return FALSE;
}

// ********************************************************************
// 声明:BOOL FASTCALL Semaphore_Close( HANDLE hSemaphore ) 
// 参数:
//	IN hSemaphore - 信号量句柄
// 返回值:
//	假如成功,返回TRUE; 否则,返回FALSE
// 功能描述:
//	删除信号量句柄及对象
// 引用:
//	被CloseHandle调用
// ********************************************************************

BOOL FASTCALL Semaphore_Close( HANDLE hSemaphore ) 
{
	return _CloseSemaphoreObj( hSemaphore, OBJ_SEMAPHORE );
}

// ********************************************************************
// 声明:HANDLE WINAPI KL_CreateMutex(
//					      LPSECURITY_ATTRIBUTES lpMutexAttributes,    // must is 0
//					      BOOL bInitialOwner,                     // flag for initial ownership
//					      LPCTSTR lpName                      // must is 0
//						)
// 参数:
//	IN lpMutexAttributes - 安全属性(必须为NULL)
//	IN bInitialOwner - 是否创建时就拥有该互斥量
//	IN lpName - 互斥量名(可以为NULL)
// 返回值:
//	假如成功,返回互斥量句柄; 否则返回NULL
// 功能描述:
//		创建互斥量, 如果lpName不为NULL,则创建一个命名互斥量,其它进程可以用同名调用该函数得到对该互斥量的跨进程引用
//	如果是命名互斥量并且多个进程会用到它,应该使bInitialOwner为FALSE。拥有互斥量的线程可以多次调用等待功能而不会
//	被锁住,这时,你应该调用同样多次释放功能(ReleaseMutex)。
//		互斥量只能被一个线程所拥有
//		用CloseHandle去删除互斥量
// 引用:
//	系统API
// ********************************************************************

HANDLE WINAPI KL_CreateMutex(
      LPSECURITY_ATTRIBUTES lpMutexAttributes,    // must is 0
      BOOL bInitialOwner,                     // flag for initial ownership
      LPCTSTR lpName                      // must is 0
     )
{
	return _CreateHandleObj( lpMutexAttributes, bInitialOwner ? 0 : 1, 1, lpName, SF_MUTEX | SF_OWNER, OBJ_MUTEX, GetAPICallerProcessPtr() );
}

// ********************************************************************
// 声明:BOOL WINAPI KL_ReleaseMutex( HANDLE hMutex )
// 参数:
//		IN hMutex - 互斥量句柄
// 返回值:
//		假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//		释放对互斥量的拥有权并使互斥量对象有信号。只有拥有该互斥量的线程才能释放它
// 引用:
//		系统API
// ********************************************************************

BOOL WINAPI KL_ReleaseMutex( HANDLE hMutex )
{
    LPSEMAPHORE lpho = HandleToPtr( hMutex, OBJ_MUTEX );	//由句柄得到对象指针
    if( lpho )	//有效吗?
	{	//是
		if( lpho->lpOwner == lpCurThread )		//是否当前线程拥有该互斥量
		{	//是
			if( lpho->nLockCount == 1 )		//当前线程重复等待该互斥量的次数是否为 1
		        return _SemaphoreRelease( lpho, 1, 0 );  // 是,释放它
			else	
			{
				lpho->nLockCount--;	//否,仅仅减去重复计数
			    return TRUE;
			}
		}
	}
	return FALSE;
}



// ********************************************************************
// 声明:HANDLE WINAPI KL_CreateEvent(
//				LPSECURITY_ATTRIBUTES lpEventAttributes,    // must is NULL
//  			BOOL bManualReset, 
//				BOOL bInitialState, 
//				LPTSTR lpName )
// 参数:
//		IN lpEventAttributes - 安全属性
//		IN bManualReset - 是否手工重设信号
//		IN bInitialState - 事件的状态,假如为TRUE,事件创建后为有信号状态
//		IN lpName - 事件名(可以为NULL)
// 返回值:
//		假如成功,返回有效的句柄值;否则,返回NULL
// 功能描述:
//	创建事件对象。假如lpName不为NULL,则创建一个其它进程可以访问的命名事件。
//	如果为命名事件且之前已经创建了该事件,则忽略bManualReset和bInitialState
//	如果bManualReset为FALSE,则当事件有信号并且有线程等待该事件,则系统释放等
//	待线程并且自动将该事件重新设为无信号状态
// 引用:
//		系统API
// ********************************************************************

HANDLE WINAPI KL_CreateEvent(
      LPSECURITY_ATTRIBUTES lpEventAttributes,    // must is NULL
  	  BOOL bManualReset, 
	  BOOL bInitialState, 
	  LPCTSTR lpName ) 
{
	UINT uiFlag;
	HANDLE h;
	if( bManualReset )
		uiFlag = SF_MANUALRESET;
	else
		uiFlag = 0;

	h = _CreateHandleObj( lpEventAttributes, bInitialState ? 1 : 0, 1, lpName, SF_EVENT | uiFlag , OBJ_EVENT, GetAPICallerProcessPtr() );
	if( h && bInitialState )
	{
	    LPVOID lpho = HandleToPtr( h, OBJ_EVENT );//由句柄得到对象指针
        _SemaphoreRelease( (LPSEMAPHORE)lpho, 1, NULL );
	}
	return h;
}

// ********************************************************************
// 声明:BOOL WINAPI KL_ResetEvent( HANDLE hEvent )
// 参数:
//		IN hEvent - 事件句柄
// 返回值:
//		假如成功,返回TRUE;否则,返回FALSE	
// 功能描述:
//		将事件对象设为无信号状态
// 引用:
//		系统API
// ********************************************************************

BOOL WINAPI KL_ResetEvent( HANDLE hEvent )
{
    LPVOID lpho = HandleToPtr( hEvent, OBJ_EVENT );	//由句柄得到对象指针
    if( lpho )//
	{	// 有效的指针
		return _SemaphoreReset( (LPSEMAPHORE)lpho );//
	}

	return FALSE;        
}

// ********************************************************************
// 声明:BOOL WINAPI KL_SetEvent( HANDLE hEvent )
// 参数:
//		IN hEvent - 事件对象句柄
// 返回值:
//		假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//		设置事件为信号状态,如果有等待的线程,则释放它们。
//		线程通过等待功能检查事件信号,当线程得到信号后,对信号的处理为下:
//		当该事件为手工重设功能,该事件的信号不会改变直到调用了ResetEvent,
//		当该事件为非手工重设功能,该信号重设为无信号。
//		仅仅只有一个等待的线程能得到信号
// 引用:
//		系统API
// ********************************************************************
BOOL WINAPI KL_SetEvent( HANDLE hEvent )
{
    LPVOID lpho = HandleToPtr( hEvent, OBJ_EVENT );//由句柄得到对象指针
    if( lpho )
	{
		return _SemaphoreRelease( (LPSEMAPHORE)lpho, 1, NULL );
	}
	return FALSE;
}

// ********************************************************************
// 声明:BOOL WINAPI KL_PulseEvent( HANDLE hEvent )
// 参数:
//		IN hEvent - 事件对象句柄
// 返回值:
//		假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//		设置事件为信号状态,如果有等待的线程,则释放它们。
//		线程通过等待功能检查事件信号,当线程得到信号后,对信号的处理为下:
//		当该事件为手工重设功能,该信号重设为无信号,
//		当该事件为非手工重设功能,该信号重设为无信号。
//		当该事件为手工重设功能,当前等待的所有线程能得到信号并被释放
//		当该事件为非手工重设功能,仅仅一个线程能得到信号
// 引用:
//	
// ********************************************************************

BOOL WINAPI KL_PulseEvent( HANDLE hEvent )
{
    LPSEMAPHORE lpho = (LPSEMAPHORE)HandleToPtr( hEvent, OBJ_EVENT );//由句柄得到对象指针
    if( lpho )
	{		
		if( lpho->semFlag & SF_MANUALRESET )
		{
			UINT uiSave;
			LockIRQSave( &uiSave );
			if(lpho->lpWaitQueue)
			{
				LPWAITQUEUE lpWaitHead = WAIT_QUEUE_HEAD( &lpho->lpWaitQueue );
				LPWAITQUEUE lpWaitQueue = lpho->lpWaitQueue;
				while( lpWaitQueue != lpWaitHead )
				{
					lpWaitQueue->lpThread->flag |= FLAG_PULSE_EVENTING;
					lpWaitQueue = lpWaitQueue->lpNext;
				}
			}
			UnlockIRQRestore( &uiSave );
		}
		
		if( _SemaphoreRelease( (LPSEMAPHORE)lpho, 1, NULL ) )
		{
			if( lpho->semFlag & SF_MANUALRESET )
			{
			    return _SemaphoreReset( (LPSEMAPHORE)lpho );
			}
		}
	}
	return FALSE;        
}

// ********************************************************************
// 声明:BOOL FASTCALL Event_Close( HANDLE hEvent )
// 参数:
//		IN hEvent - 事件对象句柄
// 返回值:
//		假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//		当系统调用CloseHandle时,如果句柄对象为事件对象,CloseHandle则会调用该函数
// 引用:
//		hmgr.c
// ********************************************************************

BOOL FASTCALL Event_Close( HANDLE hEvent ) 
{
	return _CloseSemaphoreObj( hEvent, OBJ_EVENT );
}

// ********************************************************************
// 声明:BOOL FASTCALL Mutex_Close( HANDLE hMutex )
// 参数:
//		IN hEvent - 事件对象句柄
// 返回值:
//		假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//		当系统调用CloseHandle时,如果句柄对象为Mutex对象,CloseHandle则会调用该函数
// 引用:
//		hmgr.c
// ********************************************************************

BOOL FASTCALL Mutex_Close( HANDLE hMutex )
{
	return _CloseSemaphoreObj( hMutex, OBJ_MUTEX );
}

// ********************************************************************
// 声明:VOID WINAPI KL_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
//		IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
//		无
// 功能描述:
//		创建并初始化一个冲突段对象
// 引用:
//		系统API
// ********************************************************************

VOID WINAPI KL_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
	if( lpCriticalSection )
	{
		memset( lpCriticalSection, 0, sizeof( CRITICAL_SECTION ) );
		lpCriticalSection->dwOwnerThreadId = -1;
		lpCriticalSection->hSemaphore = _CreateHandleObj( NULL, 1, 1, NULL, SF_SEMAPHORE, OBJ_SEMAPHORE, GetAPICallerProcessPtr() );//KL_CreateMutex( 0, 0, NULL );//lpCriticalSection->lpcsName );
		//ASSERT( lpCriticalSection->hSemaphore );
	}
	else
	{
		ERRORMSG( 1 , ( "KL_InitializeCriticalSection error: null ptr,pc=0x%x,proc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
	}
}


// ********************************************************************
// 声明:VOID FASTCALL KC_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
//		IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
//		无
// 功能描述:
//		创建并初始化一个冲突段对象
// 引用:
//		内部调用
// ********************************************************************

// use by kernel
#define CSF_KERNEL  0x80000000
#define CSF_DEBUG   0x00000001

VOID FASTCALL KC_InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
	memset( lpCriticalSection, 0, sizeof( CRITICAL_SECTION ) );
	lpCriticalSection->dwOwnerThreadId = -1;
    lpCriticalSection->hSemaphore = _SemaphoreCreate( NULL, 1, 1, NULL, SF_SEMAPHORE );
	//ASSERT( lpCriticalSection->hSemaphore );
	lpCriticalSection->uiFlag = CSF_KERNEL;
}

// ********************************************************************
// 声明:VOID WINAPI KL_DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
// 参数:
//		IN lpCriticalSection - CRITICAL_SECTION结构指针
// 返回值:
//		无
// 功能描述:
//		与KL_InitializeCriticalSection相反,该功能删除冲突段对象
// 引用:
//	
// ********************************************************************

VOID WINAPI KL_DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
	if( lpCriticalSection )
	{
		if( lpCriticalSection->uiFlag & CSF_KERNEL )
		{
			_CloseSemaphoreObj( lpCriticalSection->hSemaphore, 0 );
		}
		else
			KL_CloseHandle( lpCriticalSection->hSemaphore );
		lpCriticalSection->hSemaphore = NULL;
		if( lpCriticalSection->uiFlag & CSF_DEBUG )
		{
			RETAILMSG( 1, ( "DeleteCriticalSection:lpcs=0x%x,lpcsName=%s.\r\n", lpCriticalSection, lpCriticalSection->lpcsName ) );
		}
	}
	else
	{
		ERRORMSG( 1 , ( "KL_DeleteCriticalSection error: null ptr,pc=0x%x,proc=%s.\r\n", lpCurThread->lpCallStack->pfnRetAdress,lpCurThread->lpCurProcess->lpszApplicationName ) );
		DumpCallStack( lpCurThread );		
	}
}

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

VOID WINAPI KL_LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection )
{
	if( lpCriticalSection )
	{
		if( lpCriticalSection->dwOwnerThreadId == lpCurThread->dwThreadId )	//当前线程拥有该冲突段吗?
		{	//是
#ifdef __DEBUG
			if( lpCriticalSection->uiFlag & CSF_DEBUG )		//是否输出调试信息
			{	//是
				RETAILMSG( 1, ( "LeaveCriticalSection:lpcs=0x%x,lpcsName=%s,iLockCount=%d.\r\n", lpCriticalSection, lpCriticalSection->lpcsName, lpCriticalSection->iLockCount ) );
			}
#endif
			
			if( lpCriticalSection->iLockCount != 1 )  // 最后一次离开吗 ?
				lpCriticalSection->iLockCount--;  // 不是,简单的将进入数减一(同一个线程能多次进入冲突段)
			else
			{	// 是最后一次离开
				LPSEMAPHORE lpho;
				
#ifdef DEBUG_CRITSEC
				if( lpCriticalSection->lpcsName )
				{
					DWORD dwCurThreadId = KL_GetCurrentThreadId();
					RETAILMSG( 1, ( "upcs=%s, cid=0x%x, oid=0x%x, count=%d\r\n", lpCriticalSection->lpcsName, dwCurThreadId, lpCriticalSection->dwOwnerThreadId, lpCriticalSection->iLockCount ) );
				}
#endif //DEBUG_CRITSEC
				//	
				lpCriticalSection->dwOwnerThreadId |= 1;  // 阻止所有的线程操作该对象 mask all threads with the crit
				if( lpCriticalSection->uiFlag & CSF_KERNEL )	//是否是内核自己的创建的
					lpho = (LPSEMAPHORE)lpCriticalSection->hSemaphore;  // 是
				else
					lpho = HandleToPtr( lpCriticalSection->hSemaphore, -1 );	// 用户对象	
				if( lpho )
					UpCrit( lpho, lpCriticalSection );	//进入原子操作
			}
		}
		else
		{

⌨️ 快捷键说明

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