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

📄 ktmgr.cpp

📁 C写的小型操作系统源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			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 + -