📄 thread.c
字号:
// 得到线程当前的错误代码
// 引用:
// 系统API
// ********************************************************************
DWORD WINAPI KL_GetLastError( void )
{
return lpCurThread->dwErrorCode;
}
// ********************************************************************
// 声明:DWORD WINAPI KL_TlsAlloc(VOID)
// 参数:
// 无
// 返回值:
// 假如成功,返回基于0的TLS索引值;否则,返回TLS_OUT_OF_INDEXES
// 功能描述:
// 从当前线程分配一个空闲Slot索引值,如果该线程的当前进程不是该线程的拥有者(创建者),则该功能失败
// 引用:
// 系统API
// ********************************************************************
DWORD WINAPI KL_TlsAlloc(VOID)
{
LPPROCESS lpCurProcess = lpCurThread->lpCurProcess;
if( lpCurProcess == lpCurThread->lpOwnerProcess )
{
DWORD i, mask, dwOldMask;
LPDWORD lpdwMask = &lpCurProcess->dwtlsMask;
for( i = 0, mask = 1; i < TLS_ALLOCABLE_INDEXS; i++, mask <<= 1 )
{
dwOldMask = *lpdwMask; // 得到当前进程的solt mask
if( (dwOldMask & mask) == 0 ) // 没有使用吗 ?
{ // 没有,得到它
if( KL_InterlockedCompareExchange( (LPLONG)lpdwMask, dwOldMask | mask, dwOldMask ) == (LONG)dwOldMask )
{ // 成功
return i;
}
else
{ // 失败,重新开始查找
i = 0;
mask = 1;
}
}
}
}
else
{
RETAILMSG( 1, ( "error at KL_TlsAlloc: owner process != current process.\r\n" ) );
}
return TLS_OUT_OF_INDEXES;
}
// ********************************************************************
// 声明:void ClearAllThreadTlsValue( LPPROCESS lpProcess, DWORD dwTlsIndex )
// 参数:
// IN lpProcess - 进程指针
// IN dwTlsIndex - TLS索引值
// 返回值:
// 无
// 功能描述:
// 将当前进程的所有线程的tls值设为0
// 引用:
// 系统API
// ********************************************************************
static void ClearAllThreadTlsValue( LPPROCESS lpProcess, DWORD dwTlsIndex )
{
LPTHREAD lpThread;
UINT uiSave;
LockIRQSave( &uiSave );
lpThread = lpProcess->lpFirstThread;
while( lpThread )
{
lpThread->lpdwTLS[dwTlsIndex] = 0;
lpThread = lpThread->lpNextThreadInProcess;
}
UnlockIRQRestore( &uiSave );
}
// ********************************************************************
// 声明:BOOL WINAPI KL_TlsFree( DWORD dwTlsIndex )
// 参数:
// IN dwTlsIndex - TLS索引值
// 返回值:
// 假如成功,返回TRUE;否则,返回FLASE
// 功能描述:
// 释放一个TLS索引值。如果该线程的当前进程不是该线程的拥有者(创建者),则该功能失败
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_TlsFree( DWORD dwTlsIndex )
{
LPPROCESS lpCurProcess = lpCurThread->lpCurProcess;
if( lpCurProcess == lpCurThread->lpOwnerProcess )
{
DWORD dwOldMask;
LPDWORD lpdwMask = &lpCurProcess->dwtlsMask;
if( dwTlsIndex < TLS_ALLOCABLE_INDEXS )
{
ClearAllThreadTlsValue(lpCurProcess, dwTlsIndex); // 清除所有的该slot的值(设为0)
do
{
dwOldMask = *lpdwMask;
} while( KL_InterlockedCompareExchange( (LPLONG)lpdwMask, dwOldMask & (~(1<<dwTlsIndex)), dwOldMask ) != (LONG)dwOldMask );
return TRUE;
}
}
return FALSE;
}
// ********************************************************************
// 声明:LPVOID DoTlsGetValue( LPTHREAD lpThread, DWORD dwTlsIndex )
// 参数:
// IN lpThread - 线程结构指针
// IN dwTlsIndex - slot索引值
// 返回值:
// tls值
// 功能描述:
// 得到tls值
// 引用:
//
// ********************************************************************
LPVOID DoTlsGetValue( LPTHREAD lpThread, DWORD dwTlsIndex )
{
LPVOID lpRetv = NULL;
BOOL bError = FALSE;
if( dwTlsIndex < TLS_MAX_INDEXS )
{
UINT uiSave;
LockIRQSave( &uiSave );
if( lpThread->lpdwTLS )
{
lpRetv = (LPVOID)lpThread->lpdwTLS[dwTlsIndex];
}
else
{
bError = TRUE;
}
UnlockIRQRestore( &uiSave );
if( bError == FALSE )
{
if( lpRetv == NULL )
KL_SetLastError( ERROR_SUCCESS );
}
else
KL_SetLastError( ERROR_ACCESS_DENIED );
}
return lpRetv;
}
// ********************************************************************
// 声明:BOOL DoTlsSetValue( LPTHREAD lpThread, DWORD dwTlsIndex, LPVOID lpValue )
// 参数:
// IN lpThread - 线程结构指针
// IN dwTlsIndex - slot索引值
// IN lpValue - 新的值
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 设置tls值
// 引用:
//
// ********************************************************************
BOOL DoTlsSetValue( LPTHREAD lpThread, DWORD dwTlsIndex, LPVOID lpValue )
{
if( dwTlsIndex < TLS_MAX_INDEXS )
{
UINT uiSave;
LockIRQSave( &uiSave );
//ASSERT( lpThread->lpdwTLS );
if( lpThread->lpdwTLS )
lpThread->lpdwTLS[dwTlsIndex] = (DWORD)lpValue;
else
{
KL_SetLastError( ERROR_ACCESS_DENIED );
}
UnlockIRQRestore( &uiSave );
return TRUE;
}
return FALSE;
}
// ********************************************************************
// 声明:LPVOID DoTlsGetValue( LPTHREAD lpThread, DWORD dwTlsIndex )
// 参数:
// IN lpThread - 线程结构指针
// IN dwTlsIndex - slot索引值
// 返回值:
// tls值
// 功能描述:
// 得到tls值。如果该线程的当前进程不是该线程的拥有者(创建者),则该功能失败
// 引用:
// 系统API
// ********************************************************************
LPVOID WINAPI KL_TlsGetValue( DWORD dwTlsIndex )
{
if( IS_RESERVE_TLS(dwTlsIndex) ||
lpCurThread->lpCurProcess == lpCurThread->lpOwnerProcess
)
return DoTlsGetValue( lpCurThread, dwTlsIndex );
else
{
KL_SetLastError( ERROR_ACCESS_DENIED );
RETAILMSG( 1, ( "error at KL_TlsGetValue: owner process != current process.\r\n" ) );
return NULL;
}
}
// ********************************************************************
// 声明:BOOL WINAPI KL_TlsSetValue( DWORD dwTlsIndex, LPVOID lpValue )
// IN dwTlsIndex - slot索引值
// IN lpValue - 新的值
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 设置tls值。如果该线程的当前进程不是该线程的拥有者(创建者),则该功能失败
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_TlsSetValue( DWORD dwTlsIndex, LPVOID lpValue )
{
if( IS_RESERVE_TLS(dwTlsIndex) ||
lpCurThread->lpCurProcess == lpCurThread->lpOwnerProcess )
return DoTlsSetValue( lpCurThread, dwTlsIndex, lpValue );
else
{
KL_SetLastError( ERROR_ACCESS_DENIED );
RETAILMSG( 1, ( "error at KL_TlsAlloc: owner process != current process.\r\n" ) );
return NULL;
}
}
// ********************************************************************
// 声明:LPVOID WINAPI KL_TlsGetThreadValue( DWORD dwThreadId, DWORD dwTlsIndex )
// 参数:
// IN dwThreadId - 线程ID
// IN dwTlsIndex - TLS索引
// 返回值:
// 之前用TlsSetValue设置的值
// 功能描述:
// 得到线程的TLS值
// 引用:
// 系统API
// ********************************************************************
LPVOID WINAPI KL_TlsGetThreadValue( DWORD dwThreadId, DWORD dwTlsIndex )
{
LPTHREAD lpThread = _GetThreadPtr( dwThreadId );
if( lpThread )
{
return DoTlsGetValue( lpThread, dwTlsIndex );
}
else
{
KL_SetLastError( ERROR_INVALID_PARAMETER );
RETAILMSG( 1, ( "error at KL_TlsGetThreadValue: KL_GetThreadTlsValue, invalid dwThreadId=%x.\r\n", dwThreadId ) );
}
return 0;
}
// ********************************************************************
// BOOLs WINAPI KL_TlsSetThreadValue( DWORD dwThreadId, DWORD dwTlsIndex, LPVOID lpvData )
// 参数:
// IN dwThreadId - 线程ID
// IN dwTlsIndex - TLS索引
// IN lpvData - 新的TLS值
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 设置线程的 TLS 值
// 引用:
// 系统API
// ********************************************************************
BOOL WINAPI KL_TlsSetThreadValue( DWORD dwThreadId, DWORD dwTlsIndex, LPVOID lpvData )
{
LPTHREAD lpThread = _GetThreadPtr( dwThreadId );
if( lpThread )
{
return DoTlsSetValue( lpThread, dwTlsIndex, lpvData );
}
else
{
KL_SetLastError( ERROR_INVALID_PARAMETER );
RETAILMSG( 1, ( "error at KL_TlsSetThreadValue: invalid dwThreadId=%x.\r\n", dwThreadId ) );
}
return NULL;
}
// ********************************************************************
// 声明:UINT WINAPI KL_LockSchedule( void )
// 参数:
// 无
// 返回值:
// 当前锁住计数
// 功能描述:
// 锁住调度器,阻止调度器切换到其它线程
// 每调用该功能一次,锁住计数器就加一,当每调用Thread_UnlockSchedule一次,锁住计数器就减一。
// 当锁住计数器为0时,调度器可以调度。当锁住计数器大于0时,调度器被锁住,其它任何线程不能
// 抢先调度直到该线程主动放弃CPU的使用权或因为该线程等待资源而放弃CPU的使用权;当该线程再次
// 拥有资源后,调度器再次被锁住直到锁住计数器为0。
// 只有Thread_LockSchedule和Thread_UnlockSchedule功能可以改变锁住计数器的值。
// 引用:
// 系统API
// ********************************************************************
UINT WINAPI KL_LockSchedule( void )
{
LOCK_SCHE();
return lpCurThread->nLockScheCount;
}
// ********************************************************************
// 声明:UINT WINAPI KL_UnlockSchedule( void )
// 参数:
// 无
// 返回值:
// 当前锁住计数
// 功能描述:
// 每调用该功能一次,锁住计数器就减一,当每调用Thread_LockSchedule一次,锁住计数器就加一。
// 当锁住计数器为0时,调度器可以调度。当锁住计数器大于0时,调度器被锁住,其它任何线程不能
// 抢先调度直到该线程主动放弃CPU的使用权或因为该线程等待资源而放弃CPU的使用权;当该线程再
// 次拥有资源后,调度器再次被锁住直到锁住计数器为0。
// 只有Thread_LockSchedule和Thread_UnlockSchedule功能可以改变锁住计数器的值
//
// 引用:
// 系统API
// ********************************************************************
UINT WINAPI KL_UnlockSchedule( void )
{
UNLOCK_SCHE();
return lpCurThread->nLockScheCount;
}
// ********************************************************************
// 声明:UINT WINAPI KL_CaptureException( jmp_buf jmp_data )
// 参数:
// IN jmp_data - EXCEPTION_CONTEXT 结构数据,包含用户数据
// 返回值:
// 假如进入try 代码块(block),返回0;否则,返回错误代码
// 功能描述:
// 保存线程上下文,进入try代码块
// 当异常产生时,退出代码块
// 引用:
// 系统API
// ********************************************************************
#define DEBUG_ENTRYTRY 0
UINT WINAPI KL_CaptureException( LPEXCEPTION_CONTEXT jmp_data )
{
LPEXCEPTION lpexp = KHeap_Alloc( sizeof( EXCEPTION ) ); // 分配异常结构
RETAILMSG( DEBUG_ENTRYTRY, ( "KL_CaptureException entry.\r\n" ) );
if( lpexp )
{
UINT uiSave;
lpexp->jmp_data = *jmp_data;
lpexp->uiMode = lpCurThread->lpCallStack->dwStatus;
lpexp->lpOwnerProcess = GetAPICallerProcessPtr();
lpexp->lpCallStack = lpCurThread->lpCallStack->lpNext;
LockIRQSave( &uiSave );
lpexp->lpNext = lpCurThread->lpException;
lpCurThread->lpException = lpexp;
UnlockIRQRestore( &uiSave );
RETAILMSG( DEBUG_ENTRYTRY, ( "KL_CaptureException leave.\r\n" ) );
return 0;
}
WARNMSG( DEBUG_ENTRYTRY, ( "KL_CaptureException: no memory!.\r\n" ) );
return 1;
}
// ********************************************************************
// 声明:VOID WINAPI LeaveException( BOOL bException )
// 参数:
// IN bException - 当前是否异常
// 返回值:
// 无
// 功能描述:
// 如果之前有做TryEntry,这里回到TryEntry里
// 引用:
//
// ********************************************************************
#define DEBUG_LEAVE_EXCEPTION 1
VOID LeaveException( BOOL bException )
{
EXCEPTION exp, * lpexp;
UINT uiSave;
ACCESS_KEY aky;
LockIRQSave( &uiSave );
aky = lpCurThread->akyAccessKey;
if( (lpexp = lpCurThread->lpExcepti
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -