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

📄 thread.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 5 页
字号:
/******************************************************
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 + -