📄 ktmgr.cpp
字号:
lpCurrentThread->dwScheduleCounter -= 1;
if(0 == lpCurrentThread->dwScheduleCounter)
{
lpCurrentThread->dwScheduleCounter = lpCurrentThread->dwThreadPriority;
}
lpCurrentThread->dwTotalRunTime += SYSTEM_TIME_SLICE;
//LEAVE_CRITICAL_SECTION();
lpContext = &lpCurrentThread->KernelThreadContext;
//
//---------- ** debug ** -------------
//
PerfEndRecord(&TimerIntPr); //Record the current CPU clock circle counter.
//The corresponding PerfBeginRecord routine
//is called in TimerInterruptHandler routine.
PerfCommit(&TimerIntPr); //Commit the current testing.
SwitchTo(lpContext);
break; //This instruction will never reach.
case KERNEL_THREAD_STATUS_TERMINAL: //If the current kernel thread's status is
//TERMINAL,it means this kernel thread is
//fininshed to execute,and it's status has
//been modified to TERMINAL,before the kernel
//thread is put into TERMINAL queue,a timer
//interrupt occurs.
//In this case,the kernel thread should
//continue to run.
case KERNEL_THREAD_STATUS_SLEEPING:
//ENTER_CRITICAL_SECTION();
lpCurrentThread->dwScheduleCounter -= 1;
if(0 == lpCurrentThread->dwScheduleCounter)
{
lpCurrentThread->dwScheduleCounter = lpCurrentThread->dwThreadPriority;
}
lpCurrentThread->dwTotalRunTime += SYSTEM_TIME_SLICE;
//LEAVE_CRITICAL_SECTION();
lpContext = &lpCurrentThread->KernelThreadContext;
//
//---------- ** debug ** -------------
//
PerfEndRecord(&TimerIntPr); //Record the current CPU clock circle counter.
//The corresponding PerfBeginRecord routine
//is called in TimerInterruptHandler routine.
PerfCommit(&TimerIntPr); //Commit the current testing.
SwitchTo(lpContext);
break; //This instruction will never reach.
default:
break;
}
//ENTER_CRITICAL_SECTION(); //Update the members of current kernel thread object.
lpCurrentThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
lpCurrentThread->dwScheduleCounter -= 1;
if(0 == lpCurrentThread->dwScheduleCounter)
{
lpCurrentThread->dwScheduleCounter = lpCurrentThread->dwThreadPriority;
}
lpCurrentThread->dwTotalRunTime += SYSTEM_TIME_SLICE;
//LEAVE_CRITICAL_SECTION();
KernelThreadManager.lpReadyQueue->InsertIntoQueue( //Insert into ready queue.
(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
(__COMMON_OBJECT*)lpCurrentThread,
lpCurrentThread->dwScheduleCounter
);
lpNextThread = (__KERNEL_THREAD_OBJECT*)
KernelThreadManager.lpReadyQueue->GetHeaderElement( //Get next ready one.
(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
NULL);
if(NULL == lpNextThread) //If this case occurs,the system will crash.
{
PrintLine("In ScheduleFromInt,lpCurrentKernelThread != NULL.");
PrintLine(lpszCriticalMsg);
return;
}
//ENTER_CRITICAL_SECTION();
lpNextThread->dwThreadStatus = KERNEL_THREAD_STATUS_RUNNING;
KernelThreadManager.lpCurrentKernelThread = lpNextThread; //Update the current kernel thread.
//LEAVE_CRITICAL_SECTION();
lpContext = &lpNextThread->KernelThreadContext;
//
//---------- ** debug ** -------------
//
PerfEndRecord(&TimerIntPr); //Record the current CPU clock circle counter.
//The corresponding PerfBeginRecord routine
//is called in TimerInterruptHandler routine.
PerfCommit(&TimerIntPr); //Commit the current testing.
SwitchTo(lpContext); //Switch to the new kernel thread.
}
}
//SetThreadPriority.
static DWORD SetThreadPriority(__COMMON_OBJECT* lpKernelThread,DWORD dwPriority)
{
__KERNEL_THREAD_OBJECT* lpThread = NULL;
DWORD dwOldPri = PRIORITY_LEVEL_INVALID;
DWORD dwFlags = 0L;
if(NULL == lpKernelThread)
return PRIORITY_LEVEL_INVALID;
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_INVALID;
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.
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
if((0 == lpManager->dwNextWakeupTick) ||
(lpManager->dwNextWakeupTick > dwTmpCounter))
lpManager->dwNextWakeupTick = dwTmpCounter; //Update dwNextWakeupTick value.
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_SLEEPING;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags)
dwTmpCounter = MAX_DWORD_VALUE - dwTmpCounter; //Calculates the priority of the
//current kernel thread in the sleeping
//queue.
lpManager->lpSleepingQueue->InsertIntoQueue((__COMMON_OBJECT*)lpManager->lpSleepingQueue,
(__COMMON_OBJECT*)lpKernelThread,
dwTmpCounter);
lpContext = &lpKernelThread->KernelThreadContext;
lpManager->ScheduleFromProc(lpContext);
return TRUE;
}
//CancelSleep Routine.
static BOOL CancelSleep(__COMMON_OBJECT* lpThis,__COMMON_OBJECT* lpKernelThread)
{
return FALSE;
}
//SetCurrentIRQL.
static DWORD SetCurrentIRQL(__COMMON_OBJECT* lpThis,DWORD dwNewIRQL)
{
return 0L;
}
//GetCurrentIRQL.
static DWORD GetCurrentIRQL(__COMMON_OBJECT* lpThis)
{
return 0L;
}
//SetLastError.
static DWORD SetLastError(__COMMON_OBJECT* lpKernelThread,DWORD dwNewError)
{
DWORD dwOldError = 0L;
if(NULL == lpKernelThread)
return 0L;
dwOldError = ((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwLastError;
DisableInterrupt();
((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwLastError = dwNewError;
EnableInterrupt();
return dwOldError;
}
//GetLastError.
static DWORD GetLastError(__COMMON_OBJECT* lpKernelThread)
{
if(NULL == lpKernelThread)
return 0L;
return ((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwLastError;
}
//GetThreadID.
static DWORD GetThreadID(__COMMON_OBJECT* lpKernelThread)
{
if(NULL == lpKernelThread)
return 0L;
return ((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwThreadID;
}
//GetThreadStatus.
static DWORD GetThreadStatus(__COMMON_OBJECT* lpKernelThread)
{
if(NULL == lpKernelThread)
return 0L;
return ((__KERNEL_THREAD_OBJECT*)lpKernelThread)->dwThreadStatus;
}
//SetThreadStatus.
static DWORD SetThreadStatus(__COMMON_OBJECT* lpKernelThread,DWORD dwStatus)
{
return 0L;
}
//MsgQueueFull.
static BOOL MsgQueueFull(__COMMON_OBJECT* lpThread)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
if(NULL == lpThread) //Parameter check.
return FALSE;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
return MAX_KTHREAD_MSG_NUM == lpKernelThread->ucCurrentMsgNum ? TRUE : FALSE;
}
//MsgQueueEmpty.
static BOOL MsgQueueEmpty(__COMMON_OBJECT* lpThread)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
if(NULL == lpThread) //Parameter check.
return FALSE;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
return 0 == lpKernelThread->ucCurrentMsgNum ? TRUE : FALSE;
}
//SendMessage.
static BOOL MgrSendMessage(__COMMON_OBJECT* lpThread,__KERNEL_THREAD_MESSAGE* lpMsg)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
BOOL bResult = FALSE;
DWORD dwFlags = 0L;
if((NULL == lpThread) || (NULL == lpMsg)) //Parameters check.
return bResult;
if(MsgQueueFull(lpThread)) //If the queue is full.
return bResult;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
//ENTER_CRITICAL_SECTION(); //The following operation should not be
//interrupted.
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueTrial].wCommand = lpMsg->wCommand;
lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueTrial].wParam = lpMsg->wParam;
lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueTrial].dwParam = lpMsg->dwParam;
lpKernelThread->ucMsgQueueTrial ++;
if(MAX_KTHREAD_MSG_NUM == lpKernelThread->ucMsgQueueTrial)
lpKernelThread->ucMsgQueueTrial = 0;
lpKernelThread->ucCurrentMsgNum ++;
bResult = TRUE;
//LEAVE_CRITICAL_SECTION(); //Enable interrupts.
__LEAVE_CRITICAL_SECTION(NULL,dwFlags)
//
//Set the signal to indicate there is one message to be get at least.
//
lpKernelThread->lpMsgEvent->SetEvent((__COMMON_OBJECT*)(lpKernelThread->lpMsgEvent));
return bResult;
}
//GetMessage.
static BOOL MgrGetMessage(__COMMON_OBJECT* lpThread,__KERNEL_THREAD_MESSAGE* lpMsg)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags = 0L;
if((NULL == lpThread) || (NULL == lpMsg)) //Parameters check.
return FALSE;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpThread;
if(MsgQueueEmpty(lpThread))
{
lpKernelThread->lpMsgEvent->WaitForThisObject(
(__COMMON_OBJECT*)(lpKernelThread->lpMsgEvent)); //Block the current thread.
}
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags)
lpMsg->wCommand = lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueHeader].wCommand;
lpMsg->wParam = lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueHeader].wParam;
lpMsg->dwParam = lpKernelThread->KernelThreadMsg[lpKernelThread->ucMsgQueueHeader].dwParam;
lpKernelThread->ucMsgQueueHeader ++;
if(MAX_KTHREAD_MSG_NUM == lpKernelThread->ucMsgQueueHeader)
lpKernelThread->ucMsgQueueHeader = 0x0000;
lpKernelThread->ucCurrentMsgNum --;
if(0 == lpKernelThread->ucCurrentMsgNum) //The message queue is empty.
lpKernelThread->lpMsgEvent->ResetEvent((__COMMON_OBJECT*)(lpKernelThread->lpMsgEvent));
//LEAVE_CRITICAL_SECTION(); //Enable the interrupt.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -