📄 ktmgr.cpp
字号:
lpKernelThread);
}
else //Add into Suspended Queue.
{
if(!lpMgr->lpSuspendedQueue->InsertIntoQueue((__COMMON_OBJECT*)lpMgr->lpSuspendedQueue,
(__COMMON_OBJECT*)lpKernelThread,dwPriority))
goto __TERMINAL;
}
//Call the create hook.
lpMgr->CallThreadHook(THREAD_HOOK_TYPE_CREATE,lpKernelThread,
NULL);
bSuccess = TRUE; //Now,the TRANSACTION of create a kernel thread is successfully.
__TERMINAL:
if(!bSuccess)
{
//First,release the resources created successfully.
if(NULL != lpKernelThread)
ObjectManager.DestroyObject(&ObjectManager,(__COMMON_OBJECT*)lpKernelThread);
if(NULL != lpStack)
KMemFree(lpStack,KMEM_SIZE_TYPE_ANY,0L);
return NULL;
}
else
return lpKernelThread;
}
//
//DestroyKernelThread's implementation.
//The routine do the following:
// 1. Check the status of the kernel thread object will be destroyed,if the
// status is KERNEL_THREAD_STATUS_TERMINAL,then does the rest steps,else,
// simple return;
// 2. Delete the kernel thread object from Terminal Queue;
// 3. Destroy the kernel thread object by calling DestroyObject.
//
static VOID DestroyKernelThread(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpKernel)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__KERNEL_THREAD_MANAGER* lpMgr = NULL;
__PRIORITY_QUEUE* lpTerminalQueue = NULL;
LPVOID lpStack = NULL;
if((NULL == lpThis) || (NULL == lpKernel)) //Parameter check.
return;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpKernel;
lpMgr = (__KERNEL_THREAD_MANAGER*)lpThis;
if(KERNEL_THREAD_STATUS_TERMINAL != lpKernelThread->dwThreadStatus)
return;
lpTerminalQueue = lpMgr->lpTerminalQueue;
lpTerminalQueue->DeleteFromQueue((__COMMON_OBJECT*)lpTerminalQueue,
(__COMMON_OBJECT*)lpKernelThread); //Delete from terminal queue.
//Call terminal hook routine.
lpMgr->CallThreadHook(THREAD_HOOK_TYPE_TERMINAL,
lpKernelThread,NULL);
lpStack = lpKernelThread->lpInitStackPointer;
lpStack = (LPVOID)((DWORD)lpStack - lpKernelThread->dwStackSize);
KMemFree(lpStack,KMEM_SIZE_TYPE_ANY,0L); //Free the stack of the kernel thread.
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpKernelThread);
}
//SuspendKernelThread's implementation.
static BOOL SuspendKernelThread(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpKernelThread)
{
return FALSE;
}
//ResumeKernelThread's implementation.
static BOOL ResumeKernelThread(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpKernelThread)
{
return FALSE;
}
//
//ScheduleFromProc's implementation.
//This routine can be called anywhere that re-schedule is required.
//
static VOID ScheduleFromProc(__KERNEL_THREAD_CONTEXT* lpContext)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__KERNEL_THREAD_OBJECT* lpCurrent = NULL;
__KERNEL_THREAD_OBJECT* lpNew = NULL;
__KERNEL_THREAD_CONTEXT** lppOldContext = NULL;
__KERNEL_THREAD_CONTEXT** lppNewContext = NULL;
DWORD dwFlags = 0L;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpCurrent = KernelThreadManager.lpCurrentKernelThread;
switch(lpCurrent->dwThreadStatus) //Do different actions according to status.
{
case KERNEL_THREAD_STATUS_RUNNING:
lpNew = KernelThreadManager.GetScheduleKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpCurrent->dwThreadPriority); //Get a ready kernel thread.
if(NULL == lpNew) //Current one is most priority whose status is READY.
{
lpCurrent->dwTotalRunTime += SYSTEM_TIME_SLICE;
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return; //Let current kernel thread continue to run.
}
else //Should swap out current kernel thread and run next ready one.
{
lpCurrent->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
KernelThreadManager.AddReadyKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpCurrent); //Insert into ready queue.
lpNew->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
lpNew->dwTotalRunTime += SYSTEM_TIME_SLICE;
KernelThreadManager.lpCurrentKernelThread = lpNew;
//Call schedule hook before swich.
KernelThreadManager.CallThreadHook(
THREAD_HOOK_TYPE_ENDSCHEDULE | THREAD_HOOK_TYPE_BEGINSCHEDULE,
lpCurrent,lpNew);
__SaveAndSwitch(&lpCurrent->lpKernelThreadContext,
&lpNew->lpKernelThreadContext); //Switch.
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
}
break;
case KERNEL_THREAD_STATUS_READY:
lpNew = KernelThreadManager.GetScheduleKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpCurrent->dwThreadPriority); //Get a ready thread.
if(NULL == lpNew) //Should not occur.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
BUG();
return;
}
if(lpNew == lpCurrent) //The same one.
{
lpCurrent->dwTotalRunTime += SYSTEM_TIME_SLICE;
lpCurrent->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
}
else //Not the same one.
{
lpNew->dwTotalRunTime += SYSTEM_TIME_SLICE;
lpNew->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
KernelThreadManager.lpCurrentKernelThread = lpNew;
//Call schedule hook routine.
KernelThreadManager.CallThreadHook(
THREAD_HOOK_TYPE_ENDSCHEDULE | THREAD_HOOK_TYPE_BEGINSCHEDULE,
lpCurrent,lpNew);
__SaveAndSwitch(&lpCurrent->lpKernelThreadContext,
&lpNew->lpKernelThreadContext);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
}
break;
case KERNEL_THREAD_STATUS_BLOCKED:
case KERNEL_THREAD_STATUS_SUSPENDED:
case KERNEL_THREAD_STATUS_TERMINAL:
case KERNEL_THREAD_STATUS_SLEEPING:
lpNew = KernelThreadManager.GetScheduleKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
0L); //Get a ready thread to run.
if(NULL == lpNew)
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
BUG();
PrintLine("Fatal error: in ScheduleFromProc,lpNew == NULL.");
return;
}
lpNew->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
lpNew->dwTotalRunTime += SYSTEM_TIME_SLICE;
KernelThreadManager.lpCurrentKernelThread = lpNew;
//Call schedule hook.
KernelThreadManager.CallThreadHook(
THREAD_HOOK_TYPE_ENDSCHEDULE | THREAD_HOOK_TYPE_BEGINSCHEDULE,
lpCurrent,lpNew);
__SaveAndSwitch(&lpCurrent->lpKernelThreadContext,
&lpNew->lpKernelThreadContext);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
break;
default:
BUG();
break;
}
}
//ScheduleFromInt's implementation.
static VOID ScheduleFromInt(__COMMON_OBJECT* lpThis,LPVOID lpESP)
{
__KERNEL_THREAD_OBJECT* lpNextThread = NULL;
__KERNEL_THREAD_OBJECT* lpCurrentThread = NULL;
__KERNEL_THREAD_MANAGER* lpMgr = NULL;
if((NULL == lpThis) || (NULL == lpESP)) //Parameters check.
return;
lpMgr = (__KERNEL_THREAD_MANAGER*)lpThis;
if(NULL == lpMgr->lpCurrentKernelThread) //The routine is called first time.
{
lpNextThread = KernelThreadManager.GetScheduleKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
0L);
if(NULL == lpNextThread) //If this case is occurs,the system is crash.
{
BUG();
return;
}
KernelThreadManager.lpCurrentKernelThread = lpNextThread;
lpNextThread->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
lpNextThread->dwTotalRunTime += SYSTEM_TIME_SLICE;
//Call schedule hook.
KernelThreadManager.CallThreadHook(
THREAD_HOOK_TYPE_BEGINSCHEDULE,NULL,lpNextThread);
__SwitchTo(lpNextThread->lpKernelThreadContext); //Switch to this thread.
}
else //Not the first time be called.
{
lpCurrentThread = KernelThreadManager.lpCurrentKernelThread;
//This code line saves the context of current kernel thread.
lpCurrentThread->lpKernelThreadContext = (__KERNEL_THREAD_CONTEXT*)lpESP;
switch(lpCurrentThread->dwThreadStatus)
{
case KERNEL_THREAD_STATUS_BLOCKED: //Waiting shared object in process.
case KERNEL_THREAD_STATUS_TERMINAL: //In process of termination.
case KERNEL_THREAD_STATUS_SLEEPING: //In process of falling in sleep.
case KERNEL_THREAD_STATUS_SUSPENDED: //In process of being suspended.
case KERNEL_THREAD_STATUS_READY: //Wakeup immediately in another interrupt.
lpCurrentThread->dwTotalRunTime += SYSTEM_TIME_SLICE;
//lpContext = lpCurrentThread->lpKernelThreadContext;
KernelThreadManager.CallThreadHook(
THREAD_HOOK_TYPE_BEGINSCHEDULE,NULL,lpCurrentThread);
__SwitchTo(lpCurrentThread->lpKernelThreadContext);
break; //This instruction will never reach.
case KERNEL_THREAD_STATUS_RUNNING:
lpNextThread = KernelThreadManager.GetScheduleKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpCurrentThread->dwThreadPriority);
if(NULL == lpNextThread) //Current is most priority.
{
lpCurrentThread->dwTotalRunTime += SYSTEM_TIME_SLICE;
KernelThreadManager.CallThreadHook(
THREAD_HOOK_TYPE_BEGINSCHEDULE,NULL,lpCurrentThread);
__SwitchTo(lpCurrentThread->lpKernelThreadContext);
return;
}
else
{
lpCurrentThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
KernelThreadManager.AddReadyKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpCurrentThread); //Add to ready queue.
lpNextThread->dwTotalRunTime += SYSTEM_TIME_SLICE;
lpNextThread->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
lpMgr->lpCurrentKernelThread = lpNextThread;
KernelThreadManager.CallThreadHook(
THREAD_HOOK_TYPE_BEGINSCHEDULE,NULL,lpNextThread);
__SwitchTo(lpNextThread->lpKernelThreadContext);
return;
}
default:
BUG();
break;
}
}
}
//SetThreadPriority.
static DWORD SetThreadPriority(__COMMON_OBJECT* lpKernelThread,DWORD dwPriority)
{
__KERNEL_THREAD_OBJECT* lpThread = NULL;
DWORD dwOldPri = PRIORITY_LEVEL_IDLE;
DWORD dwFlags = 0L;
if(NULL == lpKernelThread)
return PRIORITY_LEVEL_IDLE;
lpThread = (__KERNEL_THREAD_OBJECT*)lpKernelThread;
dwOldPri = lpThread->dwThreadPriority;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
lpThread->dwThreadPriority = dwPriority;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags)
return dwOldPri;
}
//GetThreadPriority.
static DWORD GetThreadPriority(__COMMON_OBJECT* lpKernelThread)
{
__KERNEL_THREAD_OBJECT* lpThread = NULL;
if(NULL == lpKernelThread)
return PRIORITY_LEVEL_IDLE;
return ((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwThreadPriority;
}
//TerminalKernelThread.
static DWORD TerminalKernelThread(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpKernelThread)
{
return 0L;
}
//
//Sleep Routine.
//This routine do the following:
// 1. Updates the dwNextWakeupTick value of kernel thread manager;
// 2. Modifies the current kernel thread's status to SLEEPING;
// 3. Puts the current kernel thread into sleeping queue of kernel thread manager;
// 4. Schedules another kernel thread to.
//
static BOOL Sleep(__COMMON_OBJECT* lpThis,/*__COMMON_OBJECT* lpKernelThread,*/DWORD dwMillisecond)
{
__KERNEL_THREAD_MANAGER* lpManager = NULL;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwTmpCounter = 0L;
__KERNEL_THREAD_CONTEXT* lpContext = NULL;
DWORD dwFlags = 0L;
if((NULL == lpThis) ||
(dwMillisecond < SYSTEM_TIME_SLICE)) //Parameters check.
return FALSE;
lpManager = (__KERNEL_THREAD_MANAGER*)lpThis;
lpKernelThread = lpManager->lpCurrentKernelThread;
if(NULL == lpKernelThread) //The routine is called in system initializing process.
{
__ERROR_HANDLER(ERROR_LEVEL_CRITICAL,0L,NULL);
return FALSE;
}
dwTmpCounter = dwMillisecond / SYSTEM_TIME_SLICE;
dwTmpCounter += System.dwClockTickCounter; //Now,dwTmpCounter countains the
//tick counter value when this
//kernel thread who calls this routine
//must be waken up.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -