📄 thread.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:线程管理
版本号:2.0.0
开发时期:2000
作者:李林
修改记录:
2004-12-21, 将 thread struct 定为 4 *1024 , 其中1024 作为 loadfailuerpage,
[thread data] xxx
[thread kernel stack] xxx -> 3*1024, user by exception, int ...
[use by loadfailurepage(1024)]
2004-08-11, 不是用动态分配( WaitForSingleObject。WaitMultiSingleObject ) 信号量,涉及到 semaphpor.c thread.c sche.c
******************************************************/
#include <eframe.h>
#include <eassert.h>
#include <eobjlist.h>
#include <epheap.h>
#include <epwin.h>
#include <epalloc.h>
#include <epcore.h>
#include <coresrv.h>
#include <eerror.h>
#define MIN_STACK_SIZE (4 * 1024)
#define PROCESS_SPACE (32 * 1024 * 1024)
#define UP_PROTECT_SIZE (64*1024)
#define DOWN_PROTECT_SIZE (64*1024)
#define PROTECT_SIZE ( UP_PROTECT_SIZE + DOWN_PROTECT_SIZE )
static void DoTerminateThread( LPTHREAD lpThread, DWORD dwExitCode );
static BOOL _DeleteThreadObjectPtr( LPTHREAD lpThread );
static BOOL _FreeThreadResourceAndReschedule( void );
static VOID FreeThreadStruct( LPTHREAD lpThread );
static LPTHREAD AllocThreadStruct( VOID );
// ********************************************************************
// 声明:static void * AllocThreadStack( DWORD dwCreateFlag, LPPROCESS lpProcess, DWORD dwSize )
// 参数:
// IN dwCreateFlag - 创建标志(参考CreateThread)
// IN lpProcess - PROCESS 结构指针
// IN dwSize - 需要的栈大小
// 返回值:
// 返回分配的内存地址
// 功能描述:
// 为一个新的线程分配一个运行栈
// 引用:
//
// ********************************************************************
#define DEBUG_AllocThreadStack 0
static void * AllocThreadStack( DWORD dwCreateFlag, LPPROCESS lpProcess, DWORD dwSize )
{
#ifdef VIRTUAL_MEM
LPVOID lpStack, lpUpProtect, lpDownProtect;
DEBUGMSG( DEBUG_AllocThreadStack, ( "AllocThreadStack: use virtual mem:dwSize(0x%x) entry.\r\n", dwSize ) );
if( dwCreateFlag & CREATE_MAINTHREAD ) //是主线程吗?
{ //是,从进程空间的末端分配
DEBUGMSG( DEBUG_AllocThreadStack, ( "AllocThreadStack: main thread.\r\n" ) );
ASSERT( dwSize <= 64 * 1024 );
lpStack = KC_VirtualAlloc( (LPVOID)( lpProcess->dwVirtualAddressBase + PROCESS_SPACE - dwSize - UP_PROTECT_SIZE ), dwSize, MEM_RESERVE|MEM_AUTO_COMMIT, PAGE_READWRITE );
}
else //从进程空间的任意地方分配
lpStack = KC_VirtualAlloc( (LPVOID)( lpProcess->dwVirtualAddressBase ), dwSize, MEM_RESERVE|MEM_AUTO_COMMIT, PAGE_READWRITE );
DEBUGMSG( DEBUG_AllocThreadStack, ( "AllocThreadStack: lpStack=0x%x.\r\n", lpStack ) );
if( lpStack )
{
LPVOID p;
DEBUGMSG( DEBUG_AllocThreadStack, ( "AllocThreadStack: commit.\r\n" ) );
//提交内存
if( ( p = KC_VirtualAlloc( (LPVOID)( (DWORD)lpStack+dwSize-MIN_STACK_SIZE ), MIN_STACK_SIZE, MEM_COMMIT, PAGE_READWRITE ) ) )
{
DEBUGMSG( DEBUG_AllocThreadStack, ( "AllocThreadStack: commit ptr(0x%x).\r\n", p ) );
#ifdef __DEBUG
memset( p, 0xCCCCCCCC, MIN_STACK_SIZE );
#endif
}
else
{
RETAILMSG( 1, ( "error at AllocThreadStack: not commit success!.\r\n" ) );
}
}
else
{
RETAILMSG( 1, ( "error at AllocThreadStack: not alloc success!.\r\n" ) );
}
return lpStack;
#else
LPVOID lpStack = KL_AllocPageMem( dwSize, NULL, 0 );
DEBUGMSG( DEBUG_AllocThreadStack, ( "AllocThreadStack: call KL_AllocPageMem:dwSize(0x%x) lpStack=(0x%x) entry.\r\n", dwSize, lpStack ) );
#ifdef __DEBUG
if( lpStack )
{
memset( lpStack, 0xCCCCCCCC, dwSize );
}
#endif
return lpStack;
#endif
}
// ********************************************************************
// 声明:static void FreeThreadCallStack( CALLSTACK * lpcs )
// 参数:
// IN lpcs - CALLSTACK 结构指针
// 返回值:
// 无
// 功能描述:
// 释放线程呼叫堆结构
// 引用:
//
// ********************************************************************
#define DEBUG_FREETHREADCALLSTACK 0
static void FreeThreadCallStack( CALLSTACK * lpcs )
{
while( lpcs )
{
CALLSTACK * lpNext = lpcs->lpNext;
DEBUGMSG( DEBUG_FREETHREADCALLSTACK, ( "fcs:(0x%x), callinfo(0x%x).\r\n", lpcs, lpcs->dwCallInfo ) );
ASSERT( lpcs->dwCallInfo & CALL_ALLOC );
if( lpcs->dwCallInfo & CALL_ALLOC )
{
KHeap_Free( lpcs, sizeof( CALLSTACK ) );
}
lpcs = lpNext;
}
}
// ********************************************************************
// 声明:static void FreeThreadExcaption( CALLSTACK * lpcs )
// 参数:
// IN lpexp - LPEXCEPTION 结构指针
// 返回值:
// 无
// 功能描述:
// 释放线程的异常结构
// 引用:
//
// ********************************************************************
#define DEBUG_FreeThreadExcaption 0
static void FreeThreadExcaption( LPEXCEPTION lpexp )
{
while( lpexp )
{
LPEXCEPTION lpNext = lpexp->lpNext;
KHeap_Free( lpexp, sizeof( EXCEPTION ) );
lpexp = lpNext;
}
}
// ********************************************************************
// 声明:static void FreeThreadStack( LPPROCESS lpProcess, LPVOID lpStack, DWORD dwStackSize )
// 参数:
// IN lpProcess - PROCESS 结构指针
// IN lpStack - 栈指针
// IN dwStackSizes - 栈大小
// 返回值:
// 无
// 功能描述:
// 释放线程的栈空间
// 引用:
//
// ********************************************************************
static void FreeThreadStack( LPPROCESS lpProcess, LPVOID lpStack, DWORD dwStackSize )
{
#ifdef VIRTUAL_MEM
KC_VirtualFree( lpStack, 0, MEM_RELEASE );
#else
KL_FreePageMem( lpStack, dwStackSize );
#endif
}
// ********************************************************************
// 声明:LPTHREAD _GetThreadPtr( DWORD id )
// 参数:
// IN id - 线程ID
// 返回值:
// 线程结构指针
// 功能描述:
// 由线程ID得到线程结构指针
// 引用:
//
// ********************************************************************
LPTHREAD _GetThreadPtr( DWORD id )
{
LPTHREAD lpThread = (LPTHREAD)GET_PTR( id );
if( (LPBYTE)lpThread >= lpbSysMainMem &&
(LPBYTE)lpThread < lpbSysMainMemEnd &&
lpThread->dwThreadId == id &&
lpThread->objType == OBJ_THREAD )
return lpThread;
else
{
KL_SetLastError( ERROR_INVALID_PARAMETER );
}
RETAILMSG( 1, ( "error: invalid thread id=0x%x.\r\n", id ) );
return NULL;
}
// ********************************************************************
// 声明:void AddToProcess( LPTHREAD lpThread )
// 参数:
// IN lpThread - THREAD 结构指针
// 返回值:
// 无
// 功能描述:
// 将线程加入进程链表
// 引用:
//
// ********************************************************************
static void AddToProcess( LPTHREAD lpThread )
{
UINT uiSave;
//ASSERT( lpThread->lpNextThreadInProcess == NULL && lpThread->lpPrevThreadInProcess == NULL );
LockIRQSave( &uiSave );
// 连接到进程链表
if( (lpThread->lpNextThreadInProcess = lpThread->lpOwnerProcess->lpFirstThread) )
{
lpThread->lpOwnerProcess->lpFirstThread->lpPrevThreadInProcess = lpThread;
}
lpThread->lpOwnerProcess->lpFirstThread = lpThread;
lpThread->lpPrevThreadInProcess = NULL;
//
UnlockIRQRestore( &uiSave );
}
// ********************************************************************
// 声明:void RemoveFromProcess( LPTHREAD lpThread )
// 参数:
// IN lpThread - THREAD 结构指针
// 返回值:
// 无
// 功能描述:
// 与 AddToProcess 相反,该函数将线程从进程链表里移出
// 引用:
//
// ********************************************************************
static void RemoveFromProcess( LPTHREAD lpThread )
{
UINT uiSave;
LockIRQSave( &uiSave ); //关中断
// 移出进程链表
if( lpThread->lpPrevThreadInProcess )
lpThread->lpPrevThreadInProcess->lpNextThreadInProcess = lpThread->lpNextThreadInProcess;
else
{ // 第一个
lpThread->lpOwnerProcess->lpFirstThread = lpThread->lpNextThreadInProcess;
}
if( lpThread->lpNextThreadInProcess )
lpThread->lpNextThreadInProcess->lpPrevThreadInProcess = lpThread->lpPrevThreadInProcess;
lpThread->lpNextThreadInProcess = lpThread->lpPrevThreadInProcess = NULL;
UnlockIRQRestore( &uiSave );
}
// ********************************************************************
// 声明:DWORD WINAPI FirstThreadProc( LPVOID lParam )
// 参数:
// IN lParam - 由 CreateThread 传递的参数
// 返回值:
// 返回0
// 功能描述:
// 新线程的内核代码部分
// 引用:
// 由该代码调用 CreateThread 传递的函数入口
// ********************************************************************
static DWORD WINAPI FirstThreadProc( LPVOID lParam )
{
DWORD dwExitCode;
//EdbgOutputDebugString( "Call ThreadProc:hThread=%x,lParam=%x,ThreadID=%x.\r\n", lpCurThread->hThread, lParam, lpCurThread->dwThreadId );
// 调用CreateThread传递的函数入口
if( lpCurThread->lpCurProcess->lpMainThread == lpCurThread )
dwExitCode = ((LPTHREAD_START_ROUTINE)( lpCurThread->lpfnStartAddress ))( lParam );
else
{
dwExitCode = CallUserStartupCode( lpCurThread->lpfnStartAddress, lParam );
}
// 退出线程
KL_ExitThread( dwExitCode );
return 0;
}
// ********************************************************************
// 声明:static LPTHREAD InitThreadData(
// LPTHREAD lpThread,
// LPPROCESS lpProcess, // process
// HANDLE hThread, // thread handle
// DWORD dwStackSize, // initial thread stack size, in bytes
// DWORD dwPreservStackSize,
// LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
// LPVOID lpParameter, // argument for new thread
// DWORD dwCreationFlags,
// LPDWORD lpdwId
// )
// 参数:
// IN lpThread - THREAD 结构指针
// IN lpProcess - PROCESS 结构指针
// IN hThread - 线程句柄
// IN dwStackSize - 该线程的需要的运行栈大小
// IN dwPreservStackSize - 在已分配的栈空间里需要保留给系统用的大小, dwPreservStackSize < dwStackSize
// IN lpStartAddress - 线程启动函数入口
// IN lpParameter - 传递给线程的参数
// OUT lpdwId - 用于接受线程ID的指针
// 返回值:
//
// 功能描述:
//
// 引用:
//
// ********************************************************************
// create a thread
#define DEBUG_InitThreadData 0
static LPTHREAD InitThreadData(
LPTHREAD lpThread,
LPPROCESS lpProcess, // process
HANDLE hThread, // thread handle
DWORD dwStackSize, // initial thread stack size, in bytes
DWORD dwPreservStackSize,
LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function
LPVOID lpParameter, // argument for new thread
DWORD dwCreationFlags,
LPDWORD lpdwId
)
{
int error = 0;
LPVOID lpStack;
DEBUGMSG( DEBUG_InitThreadData, ( "InitThreadData: lpThread(0x%x) entry.\r\n", lpThread ) );
// memset( lpThread, 0, sizeof( THREAD ) ); //2004-12-21, clear before
lpThread->akyAccessKey = lpProcess->akyAccessKey | InitKernelProcess.akyAccessKey;
lpThread->dwMagic = THREAD_MAGIC;
DEBUGMSG( DEBUG_InitThreadData, ( "InitThreadData: alloc thread stack(0x%x).\r\n", dwStackSize ) );
lpStack = AllocThreadStack( dwCreationFlags, lpProcess, dwStackSize );//+ TLS_MAX_INDEXS * sizeof( DWORD ) );
if ( !lpStack )
goto ERROR_RETURN;
error = ERROR_TRY_AGAIN;
DEBUGMSG( DEBUG_InitThreadData, ( "InitThreadData: call _SemaphoreCreate.\r\n" ) );
// 创建信号量
lpThread->lpsemExit = _SemaphoreCreate( NULL, 0, 1, NULL, SF_EVENT | SF_MANUALRESET );
if( lpThread->lpsemExit == NULL )
goto ERROR_RETURN;
lpThread->lppsemWait = (LPSEMAPHORE *)KHeap_Alloc( MAX_WAITOBJS_PTR_SIZE );
if( lpThread->lppsemWait == NULL )
goto ERROR_RETURN;
// lpThread->lpCpuPTS = AllocCPUPTS();
//if( lpThread->lpCpuPTS == NULL )
//goto ERROR_RETURN;
DEBUGMSG( DEBUG_InitThreadData, ( "InitThreadData: init thread struct.\r\n" ) );
// 初始化线程结构
lpThread->objType = OBJ_THREAD;
if( dwCreationFlags & CREATE_SUSPENDED )
{
lpThread->nSuspendCount = 1;
lpThread->dwState = THREAD_SUSPENDED;
}
else
lpThread->dwState = THREAD_UNINTERRUPTIBLE;
lpThread->nCurPriority = lpThread->nOriginPriority = DEF_PRIORITY;
lpThread->nTickCount = DEF_ROTATE;//lpCurThread->nPriority >> 1;
lpThread->fPolicy = THREAD_POLICY_OTHER;
lpThread->nRotate = DEF_ROTATE;//15;//DEF_ROTATE;//
// 由线程指针得到线程 ID
*lpdwId = lpThread->dwThreadId = (DWORD)MAKE_HANDLE( lpThread );
//
lpThread->dwThreadStackSize = dwStackSize;
lpThread->lpdwThreadStack = (LPDWORD)lpStack;
// 预留 Thread local slots 的空间并初始化
// stack space format:
// low address high address
// lpStack
// [user space uuuuuuuuuuuuuuuuuuuuuuuuuuu][TLS][cmdline]
// 2004-12-30 TLS 不从 stack 中分配
//dwStackSize -= TLS_MAX_INDEXS * sizeof( DWORD ) + ( ( dwPreservStackSize + sizeof(int) - 1 ) & ( ~( sizeof(int) - 1 ) ) );
dwStackSize -= ( ( dwPreservStackSize + sizeof(int) - 1 ) & ( ~( sizeof(int) - 1 ) ) );
// 2004-12-30
lpThread->lpdwTLS = (LPDWORD)KHeap_Alloc( TLS_ALLOC_SIZE );//( (LPBYTE)lpStack + dwStackSize );
if( lpThread->lpdwTLS )
memset( lpThread->lpdwTLS, 0, TLS_ALLOC_SIZE );
else
goto ERROR_RETURN;
// user sp space start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -