?? kthread.cpp
字號:
//***********************************************************************/
// Author : Garry
// Original Date : Jun,28 2004
// Module Name : kthread.h
// Module Funciton :
// This module countains kernal thread
// implementation code.
// Last modified Author :
// Last modified Date :
// Last modified Content :
// 1.
// 2.
// Lines number :
//***********************************************************************/
#ifndef __STDAFX_H__
#include "..\INCLUDE\StdAfx.h"
#endif
//
//The following two global variables are used to control the
//kernal threads.
//Once create a kernal thread,the creat rountine will add a entry
//to the __KTHREAD_CONTROL_BLOCK* array,and make the proper
//g_bKThreadQueueStatus index to 1.
//Once delete a kernal thread,onle set the g_bKThreadQueueStatus's
//indexed value to 0.
//
__KTHREAD_CONTROL_BLOCK* g_pKThreadQueue[MAX_KTHREAD_NUM] = {0};
BYTE g_bKThreadQueueStatus[MAX_KTHREAD_NUM] = {0};
//
//The kernal thread queue pointers.
//The system maintaince some kernal thread queues,including:
//1. Ready queue,countains the kernal thread ready to run;
//2. Blocked queue,countains the blocked kernal thread;
//3. Running queue,countains the current running kernal threads;
//4. Dead queue,countains the dead kernal thread;
//5. Suspend queue,countains the suspended kernal thread.
//
static __KTHREAD_CONTROL_BLOCK* g_pReadyQueue = NULL;
static __KTHREAD_CONTROL_BLOCK* g_pBlockedQueue = NULL;
static __KTHREAD_CONTROL_BLOCK* g_pRunningQueue = NULL;
static __KTHREAD_CONTROL_BLOCK* g_pDeadQueue = NULL;
static __KTHREAD_CONTROL_BLOCK* g_pSuspendQueue = NULL;
//
//The current running kernal thread's ID.
//
static DWORD g_dwCurrentKThreadID = 1;
//
//Message queue operations.
//
//If message queue is full.
BOOL KtMsgQueueFull(__KTHREAD_CONTROL_BLOCK* pControlBlock)
{
if(NULL == pControlBlock) //Parameter check.
return FALSE;
return MAX_KTHREAD_MSG_NUM == pControlBlock->wCurrentMsgNum ? TRUE : FALSE;
}
//If message queue empty.
BOOL KtMsgQueueEmpty(__KTHREAD_CONTROL_BLOCK* pControlBlock)
{
if(NULL == pControlBlock)
return FALSE;
return 0 == pControlBlock->wCurrentMsgNum ? TRUE : FALSE;
}
//Add a message to the current kernal thread's message queue.
BOOL KtSendMessage(__KTHREAD_CONTROL_BLOCK* pControlBlock,
__KTHREAD_MSG* pMsg)
{
BOOL bResult = FALSE;
if((NULL == pControlBlock) || (NULL == pMsg)) //Parameters check.
return bResult;
if(KtMsgQueueFull(pControlBlock)) //If the queue is full.
return bResult;
//DisableInterrupt(); //The following operation should not be
//interrupted.
pControlBlock->ktmsg[pControlBlock->wTrial].wCommand = pMsg->wCommand;
pControlBlock->ktmsg[pControlBlock->wTrial].dwParam_01 = pMsg->dwParam_01;
pControlBlock->ktmsg[pControlBlock->wTrial].dwParam_02 = pMsg->dwParam_02;
pControlBlock->wTrial ++;
if(MAX_KTHREAD_MSG_NUM == pControlBlock->wTrial)
pControlBlock->wTrial = 0x0000;
pControlBlock->wCurrentMsgNum ++;
bResult = TRUE;
//EnableInterrupt(); //Enable interrupts.
return bResult;
}
//Get a message from current kernal thread's message queue and delete it from the queue.
BOOL KtGetMessage(__KTHREAD_CONTROL_BLOCK* pControlBlock,
__KTHREAD_MSG* pMsg)
{
if((NULL == pControlBlock) || (NULL == pMsg)) //Parameters check.
return FALSE;
if(KtMsgQueueEmpty(pControlBlock))
return FALSE;
//DisableInterrupt();
pMsg->wCommand = pControlBlock->ktmsg[pControlBlock->wHeader].wCommand;
pMsg->dwParam_01 = pControlBlock->ktmsg[pControlBlock->wHeader].dwParam_01;
pMsg->dwParam_02 = pControlBlock->ktmsg[pControlBlock->wHeader].dwParam_02;
pControlBlock->wHeader ++;
if(MAX_KTHREAD_MSG_NUM == pControlBlock->wHeader)
pControlBlock->wHeader = 0x0000;
pControlBlock->wCurrentMsgNum --;
//EnableInterrupt(); //Enable the interrupt.
return TRUE;
}
BOOL KtDispatchMessage(__KTHREAD_MSG* pMsg,
__KTHREAD_MSG_HANDLER msghdr)
{
if((NULL == pMsg) || (NULL == msghdr))
return FALSE;
return msghdr(pMsg->wCommand,pMsg->dwParam_01,pMsg->dwParam_01);
}
//
//Global functions implementation.
//
DWORD GetCurrentKThreadID()
{
return g_dwCurrentKThreadID;
}
//
//Create a thread,and put the thread's control block into array g_pKThreadQueue,
//and update the corresponding queue.
//If failed,it returns 0,otherwise,returns the created kernal thread's ID.
//
DWORD CreateKThread(DWORD dwStackSize, //Thread's stack size.
DWORD dwFlags, //Flags.
DWORD dwPriority, //Priority.
LPKTHREAD_ROUTINE pStartAddress, //Start running address.
LPVOID pData, //Parameter.
LPVOID /*pReserved*/) //Reserved.
{
DWORD dwKThreadID = 0x00000000;
__KTHREAD_CONTROL_BLOCK* pControlBlock = NULL;
LPVOID pStackPointer = NULL;
BOOL bFind = FALSE;
RoundTo4k(dwStackSize); //Round the stack size to 4k times.
pControlBlock = (__KTHREAD_CONTROL_BLOCK*)KMemAlloc(dwStackSize,KMEM_SIZE_TYPE_4K);
if(NULL == pControlBlock) //If can not allocate the memory.
{
return dwKThreadID;
}
MemZero((LPVOID)pControlBlock,dwStackSize); //Zero the memory allocated just now.
pControlBlock->pKThreadRoutine = pStartAddress; //Members initialization.
pControlBlock->dwKThreadPriority = dwPriority;
pControlBlock->pData = pData;
pControlBlock->wCurrentMsgNum = 0x0000;
pControlBlock->wHeader = 0x0000;
pControlBlock->wTrial = 0x0000;
//DisableInterrupt(); //Disable interrupt.
// ****************
for(dwKThreadID = 0;dwKThreadID < MAX_KTHREAD_NUM;dwKThreadID ++)
{
if(0 == g_bKThreadQueueStatus[dwKThreadID]) //Find a free control block slot.
{
bFind = TRUE;
break;
}
}
if(FALSE == bFind) //If can not find a free control block slot.
{
KMemFree((LPVOID)pControlBlock,KMEM_SIZE_TYPE_4K,dwStackSize); //Free the memory.
return 0L;
}
DisableInterrupt(); //Disable interrupt.
//******************
g_pKThreadQueue[dwKThreadID] = pControlBlock;
g_bKThreadQueueStatus[dwKThreadID] = 1; //Set the occupied flag.
dwKThreadID ++; //Increase the KThreadID.
pControlBlock->dwKThreadID = dwKThreadID;
pControlBlock->dwStackSize = dwStackSize;
switch(dwFlags) //Update the proper kernal thread queues.
//Insert the created kernal thread into
//the status queue.
{
case KTHREAD_STATUS_BLOCKED: //Insert into blocked queue.
pControlBlock->dwKThreadStatus = KTHREAD_STATUS_BLOCKED;
pControlBlock->pNext = g_pBlockedQueue;
g_pBlockedQueue = pControlBlock;
break;
case KTHREAD_STATUS_SUSPEND: //Insert it into suspended queue.
pControlBlock->dwKThreadStatus = KTHREAD_STATUS_SUSPEND;
pControlBlock->pNext = g_pSuspendQueue;
g_pSuspendQueue = pControlBlock;
break;
default: //All other status,insert into ready queue.
case KTHREAD_STATUS_READY:
case KTHREAD_STATUS_RUNNING:
pControlBlock->dwKThreadStatus = KTHREAD_STATUS_READY;
pControlBlock->pNext = g_pReadyQueue;
g_pReadyQueue = pControlBlock;
break;
}
#ifdef __I386__ //Update the x86 CPU's context.
pControlBlock->dwESP = (DWORD)pControlBlock + dwStackSize;
pControlBlock->dwEIP = (DWORD)pStartAddress;
pControlBlock->dwEFlags = 512; //*****************************
#else
#endif
EnableInterrupt(); //Enable interrupt.
//*****************
return dwKThreadID;
}
//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -