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

📄 thread.cpp

📁 一个更为先进的嵌入式操作系统.采用RMS线程调度算法,具有信号量等同步对象.亦包括GUI. 通过该系统您可以极大知道Windows的内部秘密.
💻 CPP
字号:
#include "GOS.h"
#include "thread.h"

#define MSG_WAIT 0x01L
#define PTR_MASK ~0x3L
#define REMOVEMSG(prev,pTmp,next) \
	if(pPrev)pPrev->pNext=next;else m_pMQEntry=next;\
	pTmp->pNext=m_pMQFree;m_pMQFree=pTmp

CThread::CThread()
{
	m_pMQEntry=NULL;
	m_pMQFree=NULL;
	m_pMQBuffer=NULL;
	m_pWaitObject=NULL;
	m_pStack=NULL;
	m_nPriority=0;
}

BOOL CThread::CreateThread(PVOID pParam,int nPriority,UINT nStackSize,int nFlags)
{
	PVOID pBlock;

	m_nWakeTime=GetTickCount();
	if(nFlags & CreateSuspend)
		m_nWakeTime+=MAXLONG;
	pBlock=g_pKernel->MemoryAlloc(NULL,
		nStackSize?nStackSize:ThreadDefaultStackSize);
	m_pStack=PVOID(DWORD(pBlock)+_msize(pBlock)-sizeof(DWORD));
	m_heap.Create(pBlock);
	
	g_pHAL->CreateThread(this,pParam);
	g_pKernel->ThreadTableAdd(this,nPriority);
	
	return TRUE;
}

BOOL CThread::ExitThread(DWORD dwExitCode)
{
	MsgProc(msgExitThread,dwExitCode,0);
	SetLastError(dwExitCode);
	RemoveAllMessage();
	g_pKernel->MemoryAlloc(m_heap.Delete(),0);
	g_pKernel->ThreadTableRemove(this);
	g_pHAL->ExitThread(this);
	return TRUE;
}

VOID CThread::SleepEx(LONG nMilliseconds,BOOL bSleepTo)
{
	if(bSleepTo)
		m_nWakeTime=nMilliseconds;
	else
		m_nWakeTime=GetTickCount()+nMilliseconds;
	SwitchToThread();
}


int CThread::OnRun(PVOID pData)
{
	MSG msg;

	while(GetMessage(&msg,INFINITE) && 
		!(msg.message==msgQuit && msg.pObj==this))
	{
		DispatchMessage(&msg);
	}
	ExitThread(msg.wParam);

	return msg.wParam;
}

LRESULT CThread::MsgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	switch(message)
	{
	case msgGetMQThread:
		wParam=LRESULT(this);
		break;
	case msgRunThread:
		wParam=OnRun(PVOID(wParam));
		break;
	default:
		wParam=CMsgObject::MsgProc(message,wParam,lParam);
	}	
	return wParam;
}

BOOL CThread::GetMessage(PMSG pMsg,LONG nTimeOut)
{
	PMSGLE pCur,pPrev=NULL;
	LONG nWake,nCurTime=GetTickCount();
	
	nTimeOut+=nCurTime;
	m_tlock.Lock(INFINITE);

	pCur=m_pMQEntry;
	for(;;)
	{
		if(!pCur)
		{
			if(LONG(nTimeOut-nCurTime)<=0)
				break;
			m_nWakeTime=nTimeOut;
			*PDWORD(&m_pMQBuffer) |= MSG_WAIT;
			m_tlock.Unlock();
			SwitchToThread();
			*PDWORD(&m_pMQBuffer) &= ~MSG_WAIT;
			m_tlock.Lock(INFINITE);
			pCur=m_pMQEntry;
			nCurTime=GetTickCount();
			continue;
		}
		else if(IsEventMessage(pCur->msg.message))
		{
			if(pCur->msg.pObj)
			{
				*pMsg=pCur->msg;
				pMsg->message=msgEvent;
				pCur->msg.pObj=NULL;
				break;
			}
		}
		else if(IsTimerMessage(pCur->msg.message))
		{
			nWake=pCur->msg.wParam;
			if(LONG(nCurTime-nWake)>=0)
			{
				pMsg->pObj=pCur->msg.pObj;
				pMsg->message=msgTimer;
				pMsg->wParam=LOWORD(pCur->msg.lParam);
				pMsg->lParam=nWake;

				pCur->msg.wParam=nWake=HIWORD(pCur->msg.lParam) + 
					((pMsg->wParam & 0x8000)?nWake:nCurTime);
				break;
			}
			if(LONG(nTimeOut-nWake)>0)
				nTimeOut=nWake;
		}
		else
		{
			*pMsg=pCur->msg;
			REMOVEMSG(pPrev,pCur,pCur->pNext);
			break;
		}
		pPrev=pCur;
		pCur=pCur->pNext;
	}
	m_tlock.Unlock();
	return BOOL(pCur);
}


LRESULT CThread::DispatchMessage(const MSG *pMsg)
{
	LRESULT lResult;
	CMsgObject* pObj=pMsg->pObj;

	if(pObj)
	{
		lResult=pObj->MsgProc(pMsg->message,pMsg->wParam,pMsg->lParam);
	}
	else if(pMsg->message==msgSendMessage)
	{
		CMutex* lock=(CMutex*)pMsg->wParam;
		PMSG m=PMSG(pMsg->lParam);
		m->wParam=m->pObj->MsgProc(m->message,m->wParam,m->lParam);
		lock->Unlock();
		lResult=TRUE;
	}
	else lResult=0;

	return lResult;
}

HANDLE CThread::InsertMessage(CMsgObject* pObj,UINT nMessage,WPARAM wParam,LPARAM lParam)
{
	PMSGLE pIns=NULL,pTmp,pPrev=NULL,pNext;

	m_tlock.Lock(INFINITE);
	
	for(pTmp=m_pMQEntry;pTmp;pPrev=pTmp,pTmp=pNext)
	{	
		pNext=pTmp->pNext;
		if(pTmp->msg.message>=nMessage)
		{
			if(pTmp->msg.message>nMessage)
				break;
			if(pTmp->msg.pObj==pObj && IsUniqueMessage(nMessage))
			{
				pIns=pTmp;
				break;
			}
		}
	}
	if(!pIns)
	{
		if(!m_pMQFree)
			GrowMQBuffer();
		pIns=m_pMQFree;
		m_pMQFree=pIns->pNext;

		if(pPrev)
		{
			pIns->pNext=pTmp;
			pPrev->pNext=pIns;
		}
		else
		{
			pIns->pNext=m_pMQEntry;
			m_pMQEntry=pIns;
		}
		pIns->msg.pObj=pObj;
		pIns->msg.message=nMessage;
	}
	pIns->msg.wParam=wParam;
	pIns->msg.lParam=lParam;
	
	m_tlock.Unlock();
	if(DWORD(m_pMQBuffer) & MSG_WAIT)
		SleepEx(0,FALSE);

	return HANDLE(pIns);
}

HANDLE CThread::InsertMessage(CMsgObject* pObj,HANDLE hRefMsg,WPARAM wParam,LPARAM lParam)
{
	PMSGLE pIns,pRefMsg=PMSGLE(hRefMsg);

	m_tlock.Lock(INFINITE);

	if(!m_pMQFree)
		GrowMQBuffer();
	pIns=m_pMQFree;
	m_pMQFree=pIns->pNext;
	pIns->pNext=pRefMsg->pNext;
	pRefMsg->pNext=pIns;
	
	pIns->msg.message=pRefMsg->msg.message;
	pIns->msg.pObj=pObj;
	pIns->msg.wParam=wParam;
	pIns->msg.lParam=lParam;
	
	m_tlock.Unlock();
	if(DWORD(m_pMQBuffer) & MSG_WAIT)
		SleepEx(0,FALSE);

	return HANDLE(pIns);
}

void CThread::PulseMessage(HANDLE hMsg)
{
	if(DWORD(m_pMQBuffer) & MSG_WAIT)
		SleepEx(0,FALSE);
}

BOOL CThread::RemoveMessage(CMsgObject* pObj)
{
	PMSGLE pTmp,pPrev=NULL,pNext;
	DWORD nCount=0;

	m_tlock.Lock(INFINITE);
	for(pTmp=m_pMQEntry;pTmp;pTmp=pNext)
	{	
		pNext=pTmp->pNext;
		if(pTmp->msg.pObj==pObj)
		{
			nCount++;
			REMOVEMSG(pPrev,pTmp,pNext);
		}
		pPrev=pTmp;
	}
	m_tlock.Unlock();
	return nCount;
}

BOOL CThread::RemoveMessage(CMsgObject* pObj,UINT nMessage)
{
	PMSGLE pTmp,pPrev=NULL,pNext;
	DWORD nCount=0;

	m_tlock.Lock(INFINITE);
	for(pTmp=m_pMQEntry;pTmp;pTmp=pNext)
	{	
		pNext=pTmp->pNext;
		if(pTmp->msg.message>=nMessage)
		{
			if(pTmp->msg.message>nMessage)
				break;
			if(pTmp->msg.pObj==pObj)
			{
				nCount++;
				REMOVEMSG(pPrev,pTmp,pNext);
				if(IsUniqueMessage(nMessage))
					break;
			}
		}
		pPrev=pTmp;
	}
	m_tlock.Unlock();
	return nCount;
}

BOOL CThread::RemoveMessage(HANDLE hMsgFrom,HANDLE hMsgTo)
{
	PMSGLE pFrom=PMSGLE(hMsgFrom),pTo=PMSGLE(hMsgTo);
	PMSGLE pTmp,pPrev=NULL;

	m_tlock.Lock(INFINITE);
	for(pTmp=m_pMQEntry;pTmp;pPrev=pTmp,pTmp=pTmp->pNext)
	{	
		if(pTmp==pFrom)
		{
			if(pPrev)
				pPrev->pNext=pTo->pNext;
			else
				m_pMQEntry=pTo->pNext;
			pTo->pNext=m_pMQFree;
			m_pMQFree=pFrom;
			break;
		}
	}
	m_tlock.Unlock();
	return BOOL(pTmp);
}

BOOL CThread::RemoveTimerMessage(CMsgObject* pObj,UINT nIDEvent)
{
	PMSGLE pTmp,pPrev=NULL,pNext;

	m_tlock.Lock(INFINITE);
	for(pTmp=m_pMQEntry;pTmp;pPrev=pTmp,pTmp=pNext)
	{	
		pNext=pTmp->pNext;
		if(IsTimerMessage(pTmp->msg.message))
		{
			if(pTmp->msg.pObj==pObj && LOWORD(pTmp->msg.lParam)==nIDEvent)
			{
				REMOVEMSG(pPrev,pTmp,pNext);
				break;
			}
		}
	}
	m_tlock.Unlock();

	return BOOL(pTmp);
}

BOOL CThread::GrowMQBuffer()
{
	PMSGLE pTmp,pBuf,pBufEnd;
	DWORD nSize=MsgQueueGrowSize*sizeof(MSGLE);
	
	pBuf=(PMSGLE)g_pKernel->MemoryAlloc(NULL,nSize+sizeof(PMSGLE));
	m_pMQFree=pBuf;
	pBufEnd=PMSGLE(DWORD(pBuf)+nSize);

	nSize=DWORD(m_pMQBuffer);
	pBufEnd->pNext=PMSGLE(nSize & PTR_MASK);
	nSize &= MSG_WAIT;
	nSize |= DWORD(pBuf);
	m_pMQBuffer=PMSGLE(nSize);

	for(pTmp=pBuf+1;pTmp<pBufEnd;pBuf=pTmp,pTmp++)
		pBuf->pNext=pTmp;
	pBuf->pNext=NULL;

	return TRUE;
}

void CThread::RemoveAllMessage()
{
	DWORD nSize=MsgQueueGrowSize*sizeof(MSGLE);
	PMSGLE pBufEnd,pBuf;

	m_tlock.Lock(INFINITE);
	pBuf=PMSGLE(DWORD(m_pMQBuffer) & PTR_MASK);
	m_pMQBuffer=NULL;
	m_pMQEntry=NULL;
	m_pMQFree=NULL;
	m_tlock.Unlock();

	while(pBuf)
	{
		pBufEnd=PMSGLE(DWORD(pBuf)+nSize);
		g_pKernel->MemoryAlloc(pBuf,0);
		pBuf=pBufEnd->pNext;
	}
}

⌨️ 快捷键说明

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