📄 system.cpp
字号:
//***********************************************************************/
// Author : Garry
// Original Date : Nov,06 2004
// Module Name : system.cpp
// Module Funciton :
// This module countains system mechanism releated objects's
// implementation..
// Including the following aspect:
// 1. Interrupt object and interrupt management code;
// 2. Timer object and timer management code;
// 3. System level parameters management coee,such as
// physical memory,system time,etc;
// 4. Other system mechanism releated objects.
//
// ************
// This file is one of the most important file of Hello China.
// ************
// Last modified Author :
// Last modified Date :
// Last modified Content :
// 1.
// 2.
// Lines number :
//***********************************************************************/
#ifndef __STDAFX_H__
#include "StdAfx.h"
#endif
__PERF_RECORDER TimerIntPr = {
U64_ZERO,
U64_ZERO,
U64_ZERO,
U64_ZERO}; //Performance recorder object used to mesure
//the performance of timer interrupt.
//
//TimerInterruptHandler routine.
//The following routine is the most CRITICAL routine of kernel of Hello China.
//The routine does the following:
// 1. Schedule timer object;
// 2. Update the system level variables,such as dwClockTickCounter;
// 3. Schedule kernel thread(s).
//
static BOOL TimerInterruptHandler(LPVOID lpEsp,LPVOID)
{
DWORD dwPriority = 0L;
__TIMER_OBJECT* lpTimerObject = 0L;
__KERNEL_THREAD_MESSAGE Msg ;
__PRIORITY_QUEUE* lpTimerQueue = NULL;
__PRIORITY_QUEUE* lpSleepingQueue = NULL;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags = 0L;
if(NULL == lpEsp) //Parameter check.
return TRUE;
//
// -------- ** debug ** --------------
//
PerfBeginRecord(&TimerIntPr); //Begin to record the CPU clock circle.
//The corresponding PerEndRecord call in the
//ScheduleFromInt routine.
if(System.dwClockTickCounter == System.dwNextTimerTick) //Should schedule timer.
{
lpTimerQueue = System.lpTimerQueue;
lpTimerObject = (__TIMER_OBJECT*)lpTimerQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpTimerQueue,
&dwPriority);
if(NULL == lpTimerObject)
goto __CONTINUE_1;
dwPriority = MAX_DWORD_VALUE - dwPriority;
while(dwPriority <= System.dwNextTimerTick) //Strictly speaking,the dwPriority
//variable must EQUAL System.dw-
//NextTimerTick,but in the implement-
//ing of the current version,there
//may be some error exists,so we assume
//dwPriority equal or less than dwNext-
//TimerTic.
{
if(NULL == lpTimerObject->DirectTimerHandler) //Send a message to the kernel thread.
{
Msg.wCommand = KERNEL_MESSAGE_TIMER;
Msg.dwParam = lpTimerObject->dwTimerID;
KernelThreadManager.SendMessage(
(__COMMON_OBJECT*)lpTimerObject->lpKernelThread,
&Msg);
//PrintLine("Send a timer message to kernel thread.");
}
else
{
lpTimerObject->DirectTimerHandler(
lpTimerObject->lpHandlerParam); //Call the associated handler.
}
switch(lpTimerObject->dwTimerFlags)
{
case TIMER_FLAGS_ONCE: //Delete the timer object processed just now.
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpTimerObject);
break;
case TIMER_FLAGS_ALWAYS: //Re-insert the timer object into timer queue.
dwPriority = lpTimerObject->dwTimeSpan;
dwPriority /= SYSTEM_TIME_SLICE;
dwPriority += System.dwClockTickCounter;
dwPriority = MAX_DWORD_VALUE - dwPriority;
lpTimerQueue->InsertIntoQueue((__COMMON_OBJECT*)lpTimerQueue,
(__COMMON_OBJECT*)lpTimerObject,
dwPriority);
break;
default:
break;
}
lpTimerObject = (__TIMER_OBJECT*)lpTimerQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpTimerQueue,
&dwPriority); //Check another timer object.
if(NULL == lpTimerObject)
break;
dwPriority = MAX_DWORD_VALUE - dwPriority;
}
/*ENTER_CRITICAL_SECTION();
System.dwNextTimerTick = dwPriority; //Update the dwNextTimerTick variable.
LEAVE_CRITICAL_SECTION();
dwPriority = MAX_DWORD_VALUE - dwPriority;
lpTimerQueue->InsertIntoQueue((__COMMON_OBJECT*)lpTimerQueue,
(__COMMON_OBJECT*)lpTimerObject,
dwPriority); //Re-insert the timer object into queue.*/
if(NULL == lpTimerObject) //There is no timer object in queue.
{
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
System.dwNextTimerTick = 0L;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
}
else
{
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
System.dwNextTimerTick = dwPriority; //Update the next timer tick counter.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
dwPriority = MAX_DWORD_VALUE - dwPriority;
lpTimerQueue->InsertIntoQueue((__COMMON_OBJECT*)lpTimerQueue,
(__COMMON_OBJECT*)lpTimerObject,
dwPriority);
}
}
__CONTINUE_1:
//
//The following code wakes up all kernel thread(s) whose status is SLEEPING and
//the time it(then) set is out.
//
if(System.dwClockTickCounter == KernelThreadManager.dwNextWakeupTick) //There must existes
//kernel thread(s) to
//be wake up.
{
lpSleepingQueue = KernelThreadManager.lpSleepingQueue;
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpSleepingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpSleepingQueue,
&dwPriority);
while(lpKernelThread)
{
dwPriority = MAX_DWORD_VALUE - dwPriority; //Now,dwPriority countains the tick
//counter value.
if(dwPriority > System.dwClockTickCounter)
break; //This kernel thread should not be wake up.
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
KernelThreadManager.lpReadyQueue->InsertIntoQueue(
(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
(__COMMON_OBJECT*)lpKernelThread,
lpKernelThread->dwScheduleCounter
); //Insert the waked up kernel thread into ready queue.
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpSleepingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpSleepingQueue,
&dwPriority); //Check next kernel thread in sleeping queue.
}
if(NULL == lpKernelThread)
{
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.dwNextWakeupTick = 0L;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
}
else
{
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.dwNextWakeupTick = dwPriority;
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
dwPriority = MAX_DWORD_VALUE - dwPriority;
lpSleepingQueue->InsertIntoQueue((__COMMON_OBJECT*)lpSleepingQueue,
(__COMMON_OBJECT*)lpKernelThread,
dwPriority);
}
}
goto __TERMINAL;
__TERMINAL:
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
System.dwClockTickCounter ++; //Update the system clock interrupt counter.
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.ScheduleFromInt((__COMMON_OBJECT*)&KernelThreadManager,
lpEsp);
return TRUE;
}
//
//The implementation of ConnectInterrupt routine of Interrupt Object.
//The routine do the following:
// 1. Insert the current object into interrupt object array(maintenanced by system object);
// 2. Set the object's data members correctly.
//
static BOOL ConnectInterrupt(__COMMON_OBJECT* lpThis,
__INTERRUPT_HANDLER lpInterruptHandler,
LPVOID lpHandlerParam,
UCHAR ucVector,
UCHAR ucReserved1,
UCHAR ucReserved2,
UCHAR ucInterruptMode,
BOOL bIfShared,
DWORD dwCPUMask)
{
__INTERRUPT_OBJECT* lpInterrupt = NULL;
__INTERRUPT_OBJECT* lpObjectRoot = NULL;
__SYSTEM* lpSystem = NULL;
DWORD dwFlags = 0L;
if((NULL == lpThis) || (NULL == lpInterruptHandler)) //Parameters valid check.
return FALSE;
if(ucVector >= MAX_INTERRUPT_VECTOR) //Impossible!!!
return FALSE;
lpInterrupt = (__INTERRUPT_OBJECT*)
ObjectManager.CreateObject(&ObjectManager,NULL,OBJECT_TYPE_INTERRUPT);
if(NULL == lpInterrupt) //Failed to create interrupt object.
return FALSE;
if(!lpInterrupt->Initialize((__COMMON_OBJECT*)lpInterrupt)) //Failed to initialize.
return FALSE;
lpInterrupt->lpPrevInterruptObject = NULL;
lpInterrupt->lpNextInterruptObject = NULL;
lpInterrupt->InterruptHandler = lpInterruptHandler;
lpInterrupt->lpHandlerParam = lpHandlerParam;
lpInterrupt->ucVector = ucVector;
lpObjectRoot = lpSystem->lpInterruptVector[ucVector];
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(NULL == lpObjectRoot) //If this is the first interrupt object of the vector.
{
System.lpInterruptVector[ucVector] = lpInterrupt;
}
else
{
lpInterrupt->lpNextInterruptObject = lpObjectRoot;
lpObjectRoot->lpPrevInterruptObject = lpInterrupt;
System.lpInterruptVector[ucVector] = lpInterrupt;
}
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return TRUE;
}
//
//The implementation of DisconnectInterrupt.
//
static VOID DisconnectInterrupt(__COMMON_OBJECT* lpThis,
__COMMON_OBJECT* lpInterrupt)
{
__INTERRUPT_OBJECT* lpIntObject = NULL;
__SYSTEM* lpSystem = NULL;
UCHAR ucVector = NULL;
DWORD dwFlags = 0L;
if((NULL == lpThis) || (NULL == lpInterrupt)) //Parameters check.
return;
lpSystem = (__SYSTEM*)lpThis;
lpIntObject = (__INTERRUPT_OBJECT*)lpInterrupt;
ucVector = lpIntObject->ucVector;
//ENTER_CRITICAL_SECTION();
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(NULL == lpIntObject->lpPrevInterruptObject) //This is the first interrupt object.
{
lpSystem->lpInterruptVector[ucVector] = lpIntObject->lpNextInterruptObject;
if(NULL != lpIntObject->lpNextInterruptObject) //Is not the last object.
{
lpIntObject->lpNextInterruptObject->lpPrevInterruptObject = NULL;
}
}
else //This is not the first object.
{
lpIntObject->lpPrevInterruptObject->lpNextInterruptObject = lpIntObject->lpNextInterruptObject;
if(NULL != lpIntObject->lpNextInterruptObject)
{
lpIntObject->lpNextInterruptObject->lpPrevInterruptObject = lpIntObject->lpPrevInterruptObject;
}
}
//LEAVE_CRITICAL_SECTION();
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return;
}
//
//The implementation of Initialize routine of interrupt object.
//
BOOL InterruptInitialize(__COMMON_OBJECT* lpThis)
{
__INTERRUPT_OBJECT* lpInterrupt = NULL;
if(NULL == lpThis)
return FALSE;
lpInterrupt = (__INTERRUPT_OBJECT*)lpThis;
lpInterrupt->lpPrevInterruptObject = NULL;
lpInterrupt->lpNextInterruptObject = NULL;
lpInterrupt->InterruptHandler = NULL;
lpInterrupt->lpHandlerParam = NULL;
lpInterrupt->ucVector = 0L;
return TRUE;
}
//
//The implementation of Uninitialize of interrupt object.
//This routine does nothing.
//
VOID InterruptUninitialize(__COMMON_OBJECT* lpThis)
{
return;
}
//
//The implementation of timer object.
//
BOOL TimerInitialize(__COMMON_OBJECT* lpThis) //Initializing routine of timer object.
{
__TIMER_OBJECT* lpTimer = NULL;
if(NULL == lpThis)
return FALSE;
lpTimer = (__TIMER_OBJECT*)lpThis;
lpTimer->dwTimerID = 0L;
lpTimer->dwTimeSpan = 0L;
lpTimer->lpKernelThread = NULL;
lpTimer->lpHandlerParam = NULL;
lpTimer->DirectTimerHandler = NULL;
return TRUE;
}
//
//Uninitializing routine of timer object.
//
VOID TimerUninitialize(__COMMON_OBJECT* lpThis)
{
return;
}
//-----------------------------------------------------------------------------------
//
// The implementation of system object.
//
//------------------------------------------------------------------------------------
//
//Initializing routine of system object.
//The routine do the following:
// 1. Create a priority queue,to be used as lpTimerQueue,countains the timer object;
// 2. Create an interrupt object,as TIMER interrupt object;
// 3. Initialize system level variables,such as dwPhysicalMemorySize,etc.
//
static BOOL SystemInitialize(__COMMON_OBJECT* lpThis)
{
__SYSTEM* lpSystem = NULL;
__PRIORITY_QUEUE* lpPriorityQueue = NULL;
__INTERRUPT_OBJECT* lpIntObject = NULL;
BOOL bResult = FALSE;
DWORD dwFlags = 0L;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -