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

📄 synobj.cpp

📁 自己动手写操作系统源代码,不可多得的代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//***********************************************************************/
//    Author                    : Garry
//    Original Date             : Sep 21, 2005
//    Module Name               : SYNOBJ.CPP
//    Module Funciton           : 
//                                This module countains synchronization object's implementation
//                                code.
//                                The following synchronization object(s) is(are) defined
//                                in this file:
//                                  1. EVENT
//                                  2. MUTEX
//                                  3. SEMAPHORE
//                                  4. TIMER
//
//                                ************
//                                This file is 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

//
//Routines pre-declaration.
//
static DWORD WaitForEventObject(__COMMON_OBJECT*);
static DWORD SetEvent(__COMMON_OBJECT*);
static DWORD ResetEvent(__COMMON_OBJECT*);
static DWORD WaitForEventObjectEx(__COMMON_OBJECT*,DWORD);

//---------------------------------------------------------------------------------
//
//                SYNCHRONIZATION OBJECTS
//
//----------------------------------------------------------------------------------

//
//Event object's initializing routine.
//This routine initializes the members of an event object.
//

BOOL EventInitialize(__COMMON_OBJECT* lpThis)
{
	BOOL                  bResult          = FALSE;
	__EVENT*              lpEvent          = NULL;
	__PRIORITY_QUEUE*     lpPriorityQueue  = NULL;

	if(NULL == lpThis)
		goto __TERMINAL;

	lpEvent = (__EVENT*)lpThis;

	lpPriorityQueue = (__PRIORITY_QUEUE*)
		ObjectManager.CreateObject(&ObjectManager,NULL,
		OBJECT_TYPE_PRIORITY_QUEUE);
	if(NULL == lpPriorityQueue)
		goto __TERMINAL;

	bResult = lpPriorityQueue->Initialize((__COMMON_OBJECT*)lpPriorityQueue);
	if(!bResult)
		goto __TERMINAL;

	lpEvent->lpWaitingQueue      = lpPriorityQueue;
	lpEvent->dwEventStatus       = EVENT_STATUS_OCCUPIED;
	lpEvent->SetEvent            = SetEvent;
	lpEvent->ResetEvent          = ResetEvent;
	lpEvent->WaitForThisObjectEx = WaitForEventObjectEx;
	lpEvent->WaitForThisObject   = WaitForEventObject;
	bResult                      = TRUE;

__TERMINAL:
	if(!bResult)
	{
		if(NULL != lpPriorityQueue)    //Release the priority queue.
			ObjectManager.DestroyObject(&ObjectManager,
			(__COMMON_OBJECT*)lpPriorityQueue);
	}
	return bResult;
}

//
//Event object's uninitializing routine.
//This routine calles priority queue's uninitialize routine to release
//priority queue's resource.
//

VOID EventUninitialize(__COMMON_OBJECT* lpThis)
{
	__EVENT*            lpEvent          = NULL;
	__PRIORITY_QUEUE*   lpPriorityQueue  = NULL;

	if(NULL == lpThis)
		return;

	lpEvent = (__EVENT*)lpThis;
	lpPriorityQueue = lpEvent->lpWaitingQueue;
	if(NULL != lpPriorityQueue)
		ObjectManager.DestroyObject(&ObjectManager,
		(__COMMON_OBJECT*)lpPriorityQueue);          //*******CAUTION!!!************
		//lpPriorityQueue->Uninitialize((__COMMON_OBJECT*)lpPriorityQueue);
	return;
}

//
//The implementation of SetEvent.
//This routine do the following:
// 1. Saves the previous status into a local variable;
// 2. Sets the current status of the event to EVENT_STATUS_FREE;
// 3. Wakes up all kernel thread(s) in it's waiting queue.
// 4. Returns the previous status.
//

static DWORD SetEvent(__COMMON_OBJECT* lpThis)
{
	DWORD                     dwPreviousStatus     = EVENT_STATUS_OCCUPIED;
	__EVENT*                  lpEvent              = NULL;
	__KERNEL_THREAD_OBJECT*   lpKernelThread       = NULL;
	DWORD                     dwFlags              = 0L;

	if(NULL == lpThis)
		return dwPreviousStatus;

	lpEvent = (__EVENT*)lpThis;
	dwPreviousStatus = lpEvent->dwEventStatus;
	//ENTER_CRITICAL_SECTION();
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpEvent->dwEventStatus = EVENT_STATUS_FREE;    //Set the current status to free.
	//LEAVE_CRITICAL_SECTION();
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

	lpKernelThread = (__KERNEL_THREAD_OBJECT*)
		lpEvent->lpWaitingQueue->GetHeaderElement(
		(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
		NULL);
	while(lpKernelThread)                         //Remove all kernel thread(s) from
		                                          //waiting queue,and insert them into
												  //ready queue of kernel thread,so,they
												  //would be scheduled in appropriate
												  //time.
	{
		lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
		KernelThreadManager.lpReadyQueue->InsertIntoQueue(
			(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
			(__COMMON_OBJECT*)lpKernelThread,
			lpKernelThread->dwScheduleCounter
			);
		lpKernelThread = (__KERNEL_THREAD_OBJECT*)
			lpEvent->lpWaitingQueue->GetHeaderElement(
			(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
			NULL);
	}
	return dwPreviousStatus;
}

//
//The implementation of ResetEvent.
//

static DWORD ResetEvent(__COMMON_OBJECT* lpThis)
{
	__EVENT*          lpEvent          = NULL;
	DWORD             dwPreviousStatus = 0L;
	DWORD             dwFlags          = 0L;

	if(NULL == lpThis)
		return dwPreviousStatus;

	lpEvent = (__EVENT*)lpThis;
	dwPreviousStatus = lpEvent->dwEventStatus;
	//ENTER_CRITICAL_SECTION();
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	lpEvent->dwEventStatus = EVENT_STATUS_OCCUPIED;
	//LEAVE_CRITICAL_SECTION();
	__LEAVE_CRITICAL_SECTION(NULL,dwFlags);

	return dwPreviousStatus;
}

//
//The implementation of WaitForEventObject.
//

static DWORD WaitForEventObject(__COMMON_OBJECT* lpThis)
{
	__EVENT*                      lpEvent             = NULL;
	__KERNEL_THREAD_OBJECT*       lpKernelThread      = NULL;
	__KERNEL_THREAD_CONTEXT*      lpContext           = NULL;
	DWORD                         dwFlags             = 0L;

	if(NULL == lpThis)
		return OBJECT_WAIT_FAILED;

	lpEvent = (__EVENT*)lpThis;
	//ENTER_CRITICAL_SECTION();
	__ENTER_CRITICAL_SECTION(NULL,dwFlags);
	if(EVENT_STATUS_FREE == lpEvent->dwEventStatus)
	{
		//LEAVE_CRITICAL_SECTION();
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		return OBJECT_WAIT_RESOURCE;
	}
	else
	{
		lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
		//ENTER_CRITICAL_SECTION();
		lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;  //Once the status of current
		                                                                //kernel thread is set to
		                                                                //BLOCKED,the thread will
		                                                                //never be prompted by system
		                                                                //until it gives up the CPU
		                                                                //by itself,for detail information,
		                                                                //please refer to the schedule
		                                                                //routine.
		//LEAVE_CRITICAL_SECTION();
		__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
		lpEvent->lpWaitingQueue->InsertIntoQueue(
			(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
			(__COMMON_OBJECT*)lpKernelThread,
			0L);
		lpContext = &lpKernelThread->KernelThreadContext;
		//SwitchTo(lpContext);
		KernelThreadManager.ScheduleFromProc(lpContext);
		//__asm{                  //-------- ** debug ** ------------
		//	mov eax,0x09099090
		//	mov ebx,0x09099090
		//}
	}
	return OBJECT_WAIT_RESOURCE;
}

//
//In the following section we implements the time out waiting operation.
//

typedef struct{
	__EVENT*                   lpEvent;
	__KERNEL_THREAD_OBJECT*    lpKernelThread;
	DWORD                      dwWakeupReason;
}__EVENT_CALLBACK_PARAM;    //A new type used to pass parameters to call back routine.

//
//The implementation of call back routine.
//This routine is called when timer set by WaitForThisObjectEx routine timeout.
//It does the following:
// 1. Try to delete the kernel thread object who calls WaitForThisObjectEx;
// 2. If successful,it means the kernel thread is not waken up yet,so this routine
//    wakes up the kernel thread,set wakeup reason to OBJECT_WAIT_TIME,then return;
// 3. If delete failed,it means the kernel thread is waken up now,so it only returns.
//
static DWORD EventCallback(LPVOID lpParam1)
{
	__EVENT_CALLBACK_PARAM*         lpParam        = (__EVENT_CALLBACK_PARAM*)lpParam1;
	__KERNEL_THREAD_OBJECT*         lpKernelThread = NULL;
	__EVENT*                        lpEvent        = NULL;

	if(NULL == lpParam)    //Parameter validate.
		return 0L;

	lpKernelThread = lpParam->lpKernelThread;
	lpEvent        = lpParam->lpEvent;

	if(!lpEvent->lpWaitingQueue->DeleteFromQueue(    //Try to delete the kernel thread.
		(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
		(__COMMON_OBJECT*)lpKernelThread))    //The kernel thread is waken up yet.
		return 0L;
	//
	//Delete the kernel thread successfully,so must waken up the kernel thread.
	//
	lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
	KernelThreadManager.lpReadyQueue->InsertIntoQueue(
		(__COMMON_OBJECT*)KernelThreadManager.lpReadyQueue,
		(__COMMON_OBJECT*)lpKernelThread,
		lpKernelThread->dwScheduleCounter);  //Insert into ready queue.
	lpParam->dwWakeupReason = OBJECT_WAIT_TIMEOUT;
	return 1L;
}

//
//The implementation of WaitForEventObjectEx routine.
//This routine supports time out waiting,that can be used in network protocol's
//implementation.
//
static DWORD WaitForEventObjectEx(__COMMON_OBJECT* lpObject,DWORD dwTimeOut)
{
	__EVENT*                     lpEvent         = (__EVENT*)lpObject;
	__KERNEL_THREAD_OBJECT*      lpKernelThread  = NULL;
	DWORD                        dwFlags         = 0L;
	__EVENT_CALLBACK_PARAM*      lpParam         = NULL;
	__TIMER_OBJECT*              lpTimerObject   = NULL;
	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -