📄 synobj.cpp
字号:
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(NULL,dwFlags);
if(EVENT_STATUS_FREE == lpEvent->dwEventStatus)
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return OBJECT_WAIT_RESOURCE;
}
else
{
lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
lpEvent->lpWaitingQueue->InsertIntoQueue(
(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags); //Leave critical section here is safety.
//lpContext = &lpKernelThread->KernelThreadContext;
KernelThreadManager.ScheduleFromProc(NULL);
}
return OBJECT_WAIT_RESOURCE;
}
//
//WaitForEventObjectEx's implementation.
//
static DWORD WaitForEventObjectEx(__COMMON_OBJECT* lpObject,DWORD dwMillionSecond)
{
__EVENT* lpEvent = (__EVENT*)lpObject;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags;
DWORD dwTimeOutTick;
DWORD dwTimeSpan;
if(NULL == lpObject)
{
BUG();
return OBJECT_WAIT_FAILED;
}
dwTimeOutTick = (dwMillionSecond / SYSTEM_TIME_SLICE) ?
(dwMillionSecond / SYSTEM_TIME_SLICE) : 1;
dwTimeOutTick += System.dwClockTickCounter;
__ENTER_CRITICAL_SECTION(NULL,dwFlags); //Acquire event object's spinlock.
if(EVENT_STATUS_FREE == lpEvent->dwEventStatus)
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return OBJECT_WAIT_RESOURCE;
}
//Should waiting now.
if(0 == dwMillionSecond) //Waiting zero time.
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.ScheduleFromProc(NULL);
return OBJECT_WAIT_TIMEOUT;
}
lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
while(EVENT_STATUS_FREE != lpEvent->dwEventStatus)
{
if(dwTimeOutTick <= System.dwClockTickCounter)
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return OBJECT_WAIT_TIMEOUT;
}
dwTimeSpan = (dwTimeOutTick - System.dwClockTickCounter) * SYSTEM_TIME_SLICE;
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
//Add to event object's waiting queue.
lpEvent->lpWaitingQueue->InsertIntoQueue(
(__COMMON_OBJECT*)lpEvent->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
switch(TimeOutWaiting((__COMMON_OBJECT*)lpEvent,lpEvent->lpWaitingQueue,
lpKernelThread,dwTimeSpan))
{
case OBJECT_WAIT_RESOURCE: //Should loop to while again to check the status.
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
break;
case OBJECT_WAIT_TIMEOUT:
return OBJECT_WAIT_TIMEOUT;
case OBJECT_WAIT_DELETED:
return OBJECT_WAIT_DELETED;
default:
BUG();
return OBJECT_WAIT_FAILED;
}
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return OBJECT_WAIT_RESOURCE;
}
////////////////////////////////////////////////////////////////////////////////////
//
// ------------------ ** The implementation of MUTEX object ** ---------------------
//
///////////////////////////////////////////////////////////////////////////////////
//
//The implementation of ReleaseMutex.
//
static DWORD ReleaseMutex(__COMMON_OBJECT* lpThis)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__MUTEX* lpMutex = NULL;
DWORD dwPreviousStatus = 0L;
DWORD dwFlags = 0L;
if(NULL == lpThis) //Parameter check.
return 0L;
lpMutex = (__MUTEX*)lpThis;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(lpMutex->dwWaitingNum > 0) //If there are other kernel threads waiting for this object.
lpMutex->dwWaitingNum --; //Decrement the counter.
if(0 == lpMutex->dwWaitingNum) //There is not kernel thread waiting for the object.
{
dwPreviousStatus = lpMutex->dwMutexStatus;
lpMutex->dwMutexStatus = MUTEX_STATUS_FREE; //Set to free.
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return 0L;
}
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpMutex->lpWaitingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
0L); //Get one waiting kernel thread to run.
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_RESOURCE;
KernelThreadManager.AddReadyKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpKernelThread); //Put the kernel thread to ready queue.
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.ScheduleFromProc(NULL); //Re-schedule kernel thread.
return dwPreviousStatus;
}
//
//The implementation of WaitForMutexObject.
//
static DWORD WaitForMutexObject(__COMMON_OBJECT* lpThis)
{
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
__MUTEX* lpMutex = NULL;
DWORD dwFlags = 0L;
if(NULL == lpThis) //Parameter check.
return 0L;
lpMutex = (__MUTEX*)lpThis;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(MUTEX_STATUS_FREE == lpMutex->dwMutexStatus) //If the current mutex is free.
{
lpMutex->dwMutexStatus = MUTEX_STATUS_OCCUPIED; //Modify the current status.
lpMutex->dwWaitingNum ++; //Increment the counter.
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return OBJECT_WAIT_RESOURCE; //The current kernel thread successfully occupy
//the mutex.
}
else //The status of the mutex is occupied.
{
lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
lpMutex->dwWaitingNum ++; //Increment the waiting number.
lpMutex->lpWaitingQueue->InsertIntoQueue(
(__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags); //Leave critical section here is safety.
//Reschedule all kernel thread(s).
KernelThreadManager.ScheduleFromProc(NULL);
}
return OBJECT_WAIT_RESOURCE;
}
//
//Implementation of WaitForThisObjectEx routine.
//This routine is a time out waiting routine,caller can give a time value
//to indicate how long want to wait,once exceed the time value,waiting operation
//will return,even in case of the resource is not released.
//If the time value is zero,then this routine will check the current status of
//mutex object,if free,then occupy the object and return RESOURCE,else return
//TIMEOUT,and a re-schedule is triggered.
//
static DWORD WaitForMutexObjectEx(__COMMON_OBJECT* lpThis,DWORD dwMillionSecond)
{
__MUTEX* lpMutex = (__MUTEX*)lpThis;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags;
if(NULL == lpMutex)
{
BUG();
return OBJECT_WAIT_FAILED;
}
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
if(MUTEX_STATUS_FREE == lpMutex->dwMutexStatus) //Free now.
{
lpMutex->dwMutexStatus = MUTEX_STATUS_OCCUPIED;
lpMutex->dwWaitingNum ++;
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
//KernelThreadManager.ScheduleFromProc(NULL); //Re-schedule here.
return OBJECT_WAIT_RESOURCE;
}
else //The mutex is not free now.
{
if(0 == dwMillionSecond)
{
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
KernelThreadManager.ScheduleFromProc(NULL); //Re-schedule here.
return OBJECT_WAIT_TIMEOUT;
}
lpKernelThread = KernelThreadManager.lpCurrentKernelThread;
//Waiting on mutex's waiting queue.
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_BLOCKED;
lpMutex->lpWaitingQueue->InsertIntoQueue(
(__COMMON_OBJECT*)lpMutex->lpWaitingQueue,
(__COMMON_OBJECT*)lpKernelThread,
0L);
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
return TimeOutWaiting((__COMMON_OBJECT*)lpMutex,
lpMutex->lpWaitingQueue,
lpKernelThread,
dwMillionSecond);
}
}
//
//The implementation of MutexInitialize.
//
BOOL MutexInitialize(__COMMON_OBJECT* lpThis)
{
__MUTEX* lpMutex = NULL;
__PRIORITY_QUEUE* lpQueue = NULL;
BOOL bResult = FALSE;
if(NULL == lpThis) //Parameter check.
return bResult;
lpQueue = (__PRIORITY_QUEUE*)ObjectManager.CreateObject(&ObjectManager,
NULL,
OBJECT_TYPE_PRIORITY_QUEUE);
if(NULL == lpQueue) //Failed to create priority queue.
return bResult;
if(!lpQueue->Initialize((__COMMON_OBJECT*)lpQueue)) //Initialize the queue object.
goto __TERMINAL;
lpMutex = (__MUTEX*)lpThis;
lpMutex->dwMutexStatus = MUTEX_STATUS_FREE;
lpMutex->lpWaitingQueue = lpQueue;
lpMutex->WaitForThisObject = WaitForMutexObject;
lpMutex->dwWaitingNum = 0L;
lpMutex->ReleaseMutex = ReleaseMutex;
lpMutex->WaitForThisObjectEx = WaitForMutexObjectEx;
bResult = TRUE; //Successful to initialize the mutex object.
__TERMINAL:
if(!bResult)
{
if(NULL != lpQueue) //Release the queue object.
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpQueue);
}
return bResult;
}
//
//The implementation of MutexUninitialize.
//This object support safety deleted,so in this routine,all kernel thread(s)
//must be waken up before this object is destroyed.
//
VOID MutexUninitialize(__COMMON_OBJECT* lpThis)
{
__PRIORITY_QUEUE* lpWaitingQueue = NULL;
__KERNEL_THREAD_OBJECT* lpKernelThread = NULL;
DWORD dwFlags;
if(NULL == lpThis) //parameter check.
{
BUG();
return;
}
lpWaitingQueue = ((__MUTEX*)lpThis)->lpWaitingQueue;
__ENTER_CRITICAL_SECTION(NULL,dwFlags);
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpWaitingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpWaitingQueue,
NULL);
while(lpKernelThread)
{
lpKernelThread->dwThreadStatus = KERNEL_THREAD_STATUS_READY;
lpKernelThread->dwWaitingStatus &= ~OBJECT_WAIT_MASK;
lpKernelThread->dwWaitingStatus |= OBJECT_WAIT_DELETED;
KernelThreadManager.AddReadyKernelThread(
(__COMMON_OBJECT*)&KernelThreadManager,
lpKernelThread);
lpKernelThread = (__KERNEL_THREAD_OBJECT*)lpWaitingQueue->GetHeaderElement(
(__COMMON_OBJECT*)lpWaitingQueue,
NULL);
}
__LEAVE_CRITICAL_SECTION(NULL,dwFlags);
ObjectManager.DestroyObject(&ObjectManager,
(__COMMON_OBJECT*)lpWaitingQueue);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -