📄 schedule.c
字号:
pThrdDbg->dbginfo.u.UnloadDll.lpBaseOfDll = (LPVOID)ZeroPtr(pMod->BasePtr);
if (fWait) {
SetEvent(pth->pThrdDbg->hEvent);
SC_WaitForMultiple(1,&pth->pThrdDbg->hBlockEvent,FALSE,INFINITE);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
GCFT(
LPFILETIME lpFileTime
)
{
SYSTEMTIME st;
OEMGetRealTime(&st);
KSystemTimeToFileTime(&st,lpFileTime);
KLocalFileTimeToFileTime(lpFileTime,lpFileTime);
}
void AddHandleToList (HANDLE *phList, HANDLE hObj, DWORD dwType)
{
// since all the objects have the same 'look' for the first 4 fields,
// we'll just use event to represent all.
LPEVENT lpe;
DEBUGCHK (hObj);
DEBUGCHK (((HT_EVENT == dwType) && (&hEventList == phList))
|| ((HT_MUTEX == dwType) && (&hMutexList == phList))
|| ((HT_SEMAPHORE == dwType) && (&hSemList == phList)));
lpe = (LPEVENT) GetObjectPtrByType (hObj, dwType);
DEBUGCHK (lpe);
lpe->hPrev = 0;
if (lpe->hNext = *phList) {
LPEVENT lpeNext = (LPEVENT) GetObjectPtrByType (lpe->hNext, dwType);
DEBUGCHK (lpeNext);
lpeNext->hPrev = hObj;
}
*phList = hObj;
}
void RemoveHandleFromList (HANDLE *phList, HANDLE hObj, DWORD dwType)
{
// since all the objects have the same 'look' for the first 4 fields,
// we'll just use event to represent all.
LPEVENT lpe;
DEBUGCHK (phList && *phList && hObj);
DEBUGCHK (((HT_EVENT == dwType) && (&hEventList == phList))
|| ((HT_MUTEX == dwType) && (&hMutexList == phList))
|| ((HT_SEMAPHORE == dwType) && (&hSemList == phList)));
lpe = (LPEVENT) GetObjectPtrByType (hObj, dwType);
DEBUGCHK (lpe);
if (*phList == hObj) {
// 1st element in the list, update the list
*phList = lpe->hNext;
} else {
LPEVENT lpePrev = (LPEVENT) GetObjectPtrByType (lpe->hPrev, dwType);
DEBUGCHK (lpePrev);
lpePrev->hNext = lpe->hNext;
}
if (lpe->hNext) {
LPEVENT lpeNext = (LPEVENT) GetObjectPtrByType (lpe->hNext, dwType);
DEBUGCHK (lpeNext);
lpeNext->hPrev = lpe->hPrev;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
DoLinkCritMut(
LPCRIT lpcrit,
PTHREAD pth,
BYTE prio
)
{
LPCRIT lpcrit2, lpcrit3;
BYTE prio2;
prio2 = prio/PRIORITY_LEVELS_HASHSCALE;
DEBUGCHK(prio2 < PRIORITY_LEVELS_HASHSIZE);
DEBUGCHK(IsKernelVa (lpcrit));
if (!pth->pOwnedList || (prio < pth->pOwnedList->bListedPrio)) {
// either pth doesn't own any critical section or lpcrit has higher priority
// than the ones in its 'owned list'. Make lpcrit the head of its 'owned list'
// and update its hash table
lpcrit->pPrevOwned = 0;
if (lpcrit->pNextOwned = pth->pOwnedList) {
lpcrit->pNextOwned->pPrevOwned = lpcrit;
}
lpcrit->pUpOwned = lpcrit->pDownOwned = pth->pOwnedHash[prio2] = pth->pOwnedList = lpcrit;
} else {
// pth owns a CS that has a higer priority thread blocked on it, find the right
// place to enqueue lpcrit.
if (!(lpcrit2 = pth->pOwnedHash[prio2])) {
// find the preceeding non-zero hash table entry
// bounded by PRIORITY_LEVELS_HASHSIZE
pth->pOwnedHash[prio2] = lpcrit;
while (!(lpcrit2 = pth->pOwnedHash[--prio2]))
;
}
if (prio < lpcrit2->bListedPrio) {
// insert in front of lpcrit2 and replace the hash table entry
DEBUGCHK (prio/PRIORITY_LEVELS_HASHSCALE == prio2);
lpcrit->pPrevOwned = lpcrit2->pPrevOwned;
lpcrit->pNextOwned = lpcrit2;
lpcrit->pUpOwned = lpcrit->pDownOwned = pth->pOwnedHash[prio2] = lpcrit->pPrevOwned->pNextOwned = lpcrit2->pPrevOwned = lpcrit;
} else {
// find the appropriate place to insert pth
// bounded by MAX_PRIORITY_HASHSCALE
while ((lpcrit3 = lpcrit2->pNextOwned) && (prio >= lpcrit3->bListedPrio))
lpcrit2 = lpcrit3;
DEBUGCHK (!lpcrit3 || (prio < lpcrit3->bListedPrio));
DEBUGCHK (lpcrit2->bListedPrio <= prio);
if (prio == lpcrit2->bListedPrio) {
// insert at the end of the veritcal list of lpcrit2
lpcrit->pUpOwned = lpcrit2->pUpOwned;
lpcrit->pUpOwned->pDownOwned = lpcrit2->pUpOwned = lpcrit;
lpcrit->pDownOwned = lpcrit2;
lpcrit->pPrevOwned = lpcrit->pNextOwned = 0;
} else {
// insert between lpcrit2 and lpcrit3
if (lpcrit->pNextOwned = lpcrit3)
lpcrit3->pPrevOwned = lpcrit;
lpcrit->pPrevOwned = lpcrit2;
lpcrit->pUpOwned = lpcrit->pDownOwned = lpcrit2->pNextOwned = lpcrit;
}
}
}
lpcrit->bListed = 1;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
LinkCritMut(
LPCRIT lpcrit,
PTHREAD pth,
BOOL bIsCrit
)
{
BYTE prio;
DEBUGCHK(IsKernelVa (lpcrit));
DEBUGCHK(lpcrit->bListed != 1);
if (!bIsCrit || (lpcrit->lpcs->needtrap && !GET_BURIED(pth))) {
prio = lpcrit->bListedPrio = (lpcrit->pProxList ? lpcrit->pProxList->prio : MAX_PRIORITY_LEVELS-1);
DoLinkCritMut(lpcrit,pth,prio);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
LaterLinkCritMut(
LPCRIT lpcrit,
BOOL bIsCrit
)
{
BYTE prio;
KCALLPROFON(50);
if (!lpcrit->bListed && (!bIsCrit || (lpcrit->lpcs->needtrap && !GET_BURIED(pCurThread)))) {
prio = lpcrit->bListedPrio = (lpcrit->pProxList ? lpcrit->pProxList->prio : MAX_PRIORITY_LEVELS-1);
DoLinkCritMut(lpcrit,pCurThread,prio);
}
KCALLPROFOFF(50);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
LaterLinkMutOwner(
LPMUTEX lpm
)
{
BYTE prio;
KCALLPROFON(55);
if (!lpm->bListed) {
prio = lpm->bListedPrio = (lpm->pProxList ? lpm->pProxList->prio : MAX_PRIORITY_LEVELS-1);
DoLinkCritMut((LPCRIT)lpm,lpm->pOwner,prio);
}
KCALLPROFOFF(55);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
UnlinkCritMut(
LPCRIT lpcrit,
PTHREAD pth
)
{
LPCRIT pDown, pNext;
WORD prio;
if (lpcrit->bListed == 1) {
prio = lpcrit->bListedPrio/PRIORITY_LEVELS_HASHSCALE;
DEBUGCHK(prio < PRIORITY_LEVELS_HASHSIZE);
pDown = lpcrit->pDownOwned;
pNext = lpcrit->pNextOwned;
if (pth->pOwnedHash[prio] == lpcrit) {
pth->pOwnedHash[prio] = ((pDown != lpcrit) ? pDown :
(pNext && (pNext->bListedPrio/PRIORITY_LEVELS_HASHSCALE == prio)) ? pNext : 0);
}
if (pDown == lpcrit) {
if (!lpcrit->pPrevOwned) {
DEBUGCHK(pth->pOwnedList == lpcrit);
if (pth->pOwnedList = pNext)
pNext->pPrevOwned = 0;
} else {
if (lpcrit->pPrevOwned->pNextOwned = pNext)
pNext->pPrevOwned = lpcrit->pPrevOwned;
}
} else {
pDown->pUpOwned = lpcrit->pUpOwned;
lpcrit->pUpOwned->pDownOwned = pDown;
if (lpcrit->pPrevOwned) {
lpcrit->pPrevOwned->pNextOwned = pDown;
pDown->pPrevOwned = lpcrit->pPrevOwned;
goto FinishDequeue;
} else if (lpcrit == pth->pOwnedList) {
pth->pOwnedList = pDown;
DEBUGCHK(!pDown->pPrevOwned);
FinishDequeue:
if (pNext) {
pNext->pPrevOwned = pDown;
pDown->pNextOwned = pNext;
}
}
}
lpcrit->bListed = 0;
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
PreUnlinkCritMut(
LPCRIT lpcrit
)
{
KCALLPROFON(51);
UnlinkCritMut(lpcrit,pCurThread);
SET_NOPRIOCALC(pCurThread);
KCALLPROFOFF(51);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
PostUnlinkCritMut(void)
{
WORD prio, prio2;
KCALLPROFON(52);
CLEAR_NOPRIOCALC(pCurThread);
prio = GET_BPRIO(pCurThread);
if (pCurThread->pOwnedList && (prio > (prio2 = pCurThread->pOwnedList->bListedPrio)))
prio = prio2;
if (prio != GET_CPRIO(pCurThread)) {
SET_CPRIO(pCurThread,prio);
if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {
CELOG_SystemInvert(pCurThread->hTh, prio);
}
if (RunList.pRunnable && (prio > GET_CPRIO(RunList.pRunnable)))
SetReschedule();
}
KCALLPROFOFF(52);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
ReprioCritMut(
LPCRIT lpcrit,
PTHREAD pth
)
{
BYTE prio;
if (lpcrit->bListed == 1) {
UnlinkCritMut(lpcrit,pth);
prio = lpcrit->bListedPrio = (lpcrit->pProxList ? lpcrit->pProxList->prio : MAX_PRIORITY_LEVELS-1);
DoLinkCritMut(lpcrit,pth,prio);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
VOID
MakeRun(
PTHREAD pth
)
{
DWORD prio, prio2;
PTHREAD pth2, pth3;
if (!pth->bSuspendCnt) {
SET_RUNSTATE(pth,RUNSTATE_RUNNABLE);
prio = GET_CPRIO(pth);
prio2 = prio/PRIORITY_LEVELS_HASHSCALE;
if (!(pth2 = RunList.pRunnable) || (prio < GET_CPRIO(pth2))) {
// either there is no runnable or we're the highest priority thread
// make pth the head of runable and update the hash table
pth->pPrevSleepRun = 0;
if (pth->pNextSleepRun = pth2) {
pth2->pPrevSleepRun = pth;
}
pth->pUpRun = pth->pDownRun = RunList.pHashThread[prio2] = pth;
RunList.pRunnable = pth;
// see if we need to reschedule
if (!RunList.pth || (prio < GET_CPRIO(RunList.pth)))
SetReschedule();
} else {
// there are higher priority thread than pth, find the right
// place to enqueue it.
if (!(pth2 = RunList.pHashThread[prio2])) {
// find the preceeding non-zero hash table entry
// bounded by PRIORITY_LEVELS_HASHSIZE
RunList.pHashThread[prio2] = pth;
while (!(pth2 = RunList.pHashThread[-- prio2]))
;
}
if (prio < GET_CPRIO(pth2)) {
// insert into runlist and replace the hash table entry
DEBUGCHK (prio/PRIORITY_LEVELS_HASHSCALE == prio2);
pth->pPrevSleepRun = pth2->pPrevSleepRun;
pth->pNextSleepRun = pth2;
pth->pUpRun = pth->pDownRun = RunList.pHashThread[prio2] = pth->pPrevSleepRun->pNextSleepRun = pth2->pPrevSleepRun = pth;
} else {
// find the appropriate place to insert pth
// bounded by MAX_PRIORITY_HASHSCALE
while ((pth3 = pth2->pNextSleepRun) && (prio >= GET_CPRIO(pth3)))
pth2 = pth3;
DEBUGCHK (!pth3 || (prio < GET_CPRIO(pth3)));
DEBUGCHK (GET_CPRIO (pth2) <= prio);
if (prio == GET_CPRIO(pth2)) {
pth->pUpRun = pth2->pUpRun;
pth->pUpRun->pDownRun = pth2->pUpRun = pth;
pth->pDownRun = pth2;
pth->pPrevSleepRun = pth->pNextSleepRun = 0;
} else {
// insert between pth2 and pth3
if (pth->pNextSleepRun = pth3) {
pth3->pPrevSleepRun = pth;
}
pth->pPrevSleepRun = pth2;
pth2->pNextSleepRun = pth->pUpRun = pth->pDownRun = pth;
}
}
}
} else {
DEBUGCHK(!((pth->wInfo >> DEBUG_LOOPCNT_SHIFT) & 1));
SET_RUNSTATE(pth,RUNSTATE_BLOCKED);
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
RunqDequeue(
PTHREAD pth,
DWORD cprio
)
{
PTHREAD pDown, pNext;
DWORD prio = cprio/PRIORITY_LEVELS_HASHSCALE;
DEBUGCHK (!GET_SLEEPING (pth));
DEBUGCHK (!pth->pUpSleep);
// check if there is a hanging tail of the thread...
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -