📄 schedule.c
字号:
}
}
}
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 (!RunList.pRunnable) {
pth->pPrevSleepRun = pth->pNextSleepRun = 0;
pth->pUpRun = pth->pDownRun = RunList.pHashThread[prio2] = RunList.pRunnable = pth;
} else if (prio < GET_CPRIO(RunList.pRunnable)) {
pth->pPrevSleepRun = 0;
pth->pUpRun = pth->pDownRun = RunList.pHashThread[prio2] = RunList.pRunnable->pPrevSleepRun = pth;
pth->pNextSleepRun = RunList.pRunnable;
RunList.pRunnable = pth;
} else if (pth2 = RunList.pHashThread[prio2]) {
if (prio < GET_CPRIO(pth2)) {
pth->pPrevSleepRun = pth2->pPrevSleepRun;
pth->pNextSleepRun = pth2;
pth->pUpRun = pth->pDownRun = RunList.pHashThread[prio2] = pth->pPrevSleepRun->pNextSleepRun = pth2->pPrevSleepRun = pth;
} else {
FinishMakeRun:
// bounded by MAX_PRIORITY_HASHSCALE
while ((pth3 = pth2->pNextSleepRun) && (prio > GET_CPRIO(pth3)))
pth2 = pth3;
if (prio == GET_CPRIO(pth2)) {
pth->pUpRun = pth2->pUpRun;
pth->pUpRun->pDownRun = pth2->pUpRun = pth;
pth->pDownRun = pth2;
pth->pPrevSleepRun = pth->pNextSleepRun = 0;
} else if (!pth3) {
pth->pNextSleepRun = 0;
pth->pPrevSleepRun = pth2;
pth->pUpRun = pth->pDownRun = pth2->pNextSleepRun = pth;
} else {
if (prio == GET_CPRIO(pth3)) {
pth->pUpRun = pth3->pUpRun;
pth->pUpRun->pDownRun = pth3->pUpRun = pth;
pth->pDownRun = pth3;
pth->pPrevSleepRun = pth->pNextSleepRun = 0;
} else {
pth->pUpRun = pth->pDownRun = pth2->pNextSleepRun = pth3->pPrevSleepRun = pth;
pth->pPrevSleepRun = pth2;
pth->pNextSleepRun = pth3;
}
}
}
} else {
RunList.pHashThread[prio2] = pth;
// bounded by PRIORITY_LEVELS_HASHSIZE
while (!(pth2 = RunList.pHashThread[--prio2]))
;
goto FinishMakeRun;
}
if (!RunList.pth || (prio < GET_CPRIO(RunList.pth)))
SetReschedule();
} else {
DEBUGCHK(!((pth->wInfo >> DEBUG_LOOPCNT_SHIFT) & 1));
SET_RUNSTATE(pth,RUNSTATE_BLOCKED);
}
}
void SleepqDequeue(PTHREAD pth) {
PTHREAD pth2;
DEBUGCHK(GET_SLEEPING(pth));
pth->wCount++;
if (SleepList == pth) {
DEBUGCHK(!pth->pPrevSleepRun);
if (SleepList = pth->pNextSleepRun) {
SleepList->pPrevSleepRun = 0;
if (!(SleepList->dwSleepCnt += pth->dwSleepCnt)) {
++SleepList->dwSleepCnt;
++ticksleft;
}
dwSleepMin = SleepList->dwSleepCnt;
} else
dwSleepMin = 0;
dwPartialDiffMSec = 0;
} else {
DEBUGCHK(pth->pPrevSleepRun);
pth2 = pth->pNextSleepRun;
if (pth->pPrevSleepRun->pNextSleepRun = pth2) {
pth2->pPrevSleepRun = pth->pPrevSleepRun;
pth2->dwSleepCnt += pth->dwSleepCnt;
}
}
CLEAR_SLEEPING(pth);
}
VOID MakeRunIfNeeded(HANDLE hth) {
PTHREAD pth;
KCALLPROFON(39);
if ((pth = HandleToThread(hth)) && (GET_RUNSTATE(pth) == RUNSTATE_NEEDSRUN)) {
if (GET_SLEEPING(pth))
SleepqDequeue(pth);
MakeRun(pth);
}
KCALLPROFOFF(39);
}
VOID DequeueFlatProxy(LPPROXY pprox) {
LPPROXY pDown;
LPEVENT pObject;
KCALLPROFON(54);
DEBUGCHK((pprox->bType == SH_CURPROC) || (pprox->bType == SH_CURTHREAD) || (pprox->bType == HT_MANUALEVENT));
if (pDown = pprox->pQDown) { // not already dequeued
if (pprox->pQPrev) { // we're first
pObject = ((LPEVENT)pprox->pQPrev);
DEBUGCHK(pObject->pProxList == pprox);
if (pDown == pprox) { // we're alone
pObject->pProxList = 0;
} else {
pDown->pQUp = pprox->pQUp;
pprox->pQUp->pQDown = pObject->pProxList = pDown;
pDown->pQPrev = (LPPROXY)pObject;
}
} else {
pDown->pQUp = pprox->pQUp;
pprox->pQUp->pQDown = pDown;
}
pprox->pQDown = 0;
}
KCALLPROFOFF(54);
}
BOOL DequeuePrioProxy(LPPROXY pprox) {
LPCRIT lpcrit;
LPPROXY pDown, pNext;
WORD prio;
BOOL bRet;
KCALLPROFON(31);
DEBUGCHK((pprox->bType == HT_EVENT) || (pprox->bType == HT_CRITSEC) || (pprox->bType == HT_MUTEX) || (pprox->bType == HT_SEMAPHORE));
bRet = FALSE;
if (pDown = pprox->pQDown) { // not already dequeued
lpcrit = (LPCRIT)pprox->pObject;
prio = pprox->prio/PRIORITY_LEVELS_HASHSCALE;
pDown = pprox->pQDown;
pNext = pprox->pQNext;
if (lpcrit->pProxHash[prio] == pprox) {
lpcrit->pProxHash[prio] = ((pDown != pprox) ? pDown :
(pNext && (pNext->prio/PRIORITY_LEVELS_HASHSCALE == prio)) ? pNext : 0);
}
if (pDown == pprox) {
if (!pprox->pQPrev) {
DEBUGCHK(lpcrit->pProxList == pprox);
if (lpcrit->pProxList = pNext)
pNext->pQPrev = 0;
bRet = TRUE;
} else {
if (pprox->pQPrev->pQNext = pNext)
pNext->pQPrev = pprox->pQPrev;
}
} else {
pDown->pQUp = pprox->pQUp;
pprox->pQUp->pQDown = pDown;
if (pprox->pQPrev) {
pprox->pQPrev->pQNext = pDown;
pDown->pQPrev = pprox->pQPrev;
goto FinishDequeue;
} else if (pprox == lpcrit->pProxList) {
lpcrit->pProxList = pDown;
DEBUGCHK(!pDown->pQPrev);
FinishDequeue:
if (pNext) {
pNext->pQPrev = pDown;
pDown->pQNext = pNext;
}
}
}
pprox->pQDown = 0;
}
KCALLPROFOFF(31);
return bRet;
}
void DoReprioCrit(LPCRIT lpcrit) {
HANDLE hth;
PTHREAD pth;
KCALLPROFON(4);
if ((hth = lpcrit->lpcs->OwnerThread) && (pth = HandleToThread((HANDLE)((DWORD)hth & ~1))))
ReprioCritMut(lpcrit,pth);
KCALLPROFOFF(4);
}
void DoReprioMutex(LPMUTEX lpm) {
KCALLPROFON(29);
if (lpm->pOwner)
ReprioCritMut((LPCRIT)lpm,lpm->pOwner);
KCALLPROFOFF(29);
}
void DequeueProxy(LPPROXY pProx) {
switch (pProx->bType) {
case SH_CURPROC:
case SH_CURTHREAD:
case HT_MANUALEVENT:
KCall((PKFN)DequeueFlatProxy,pProx);
break;
case HT_MUTEX:
if (KCall((PKFN)DequeuePrioProxy,pProx))
KCall((PKFN)DoReprioMutex,pProx->pObject);
break;
case HT_CRITSEC:
if (KCall((PKFN)DequeuePrioProxy,pProx))
KCall((PKFN)DoReprioCrit,pProx->pObject);
break;
case HT_EVENT:
case HT_SEMAPHORE:
KCall((PKFN)DequeuePrioProxy,pProx);
break;
default:
DEBUGCHK(0);
}
}
void BoostCPrio(PTHREAD pth, DWORD prio) {
DWORD oldcprio;
oldcprio = GET_CPRIO(pth);
SET_CPRIO(pth,prio);
if (GET_RUNSTATE(pth) == RUNSTATE_RUNNABLE) {
RunqDequeue(pth,oldcprio);
MakeRun(pth);
}
}
void PostBoostMut(LPMUTEX lpm) {
PTHREAD pth;
WORD prio;
KCALLPROFON(56);
if (pCurThread->bWaitState == WAITSTATE_PROCESSING) {
pth = lpm->pOwner;
DEBUGCHK(pth);
prio = GET_CPRIO(pCurThread);
if (prio < GET_CPRIO(pth)) {
BoostCPrio(pth,prio);
CELOG_SystemInvert(pth->hTh, prio);
}
if (!GET_NOPRIOCALC(pth))
LaterLinkMutOwner(lpm);
ReprioCritMut((LPCRIT)lpm,pth);
}
KCALLPROFOFF(56);
}
void PostBoostCrit1(LPCRIT pcrit) {
PTHREAD pth;
KCALLPROFON(57);
if (pCurThread->bWaitState == WAITSTATE_PROCESSING) {
pth = HandleToThread((HANDLE)((DWORD)pcrit->lpcs->OwnerThread & ~1));
DEBUGCHK(pth);
ReprioCritMut(pcrit,pth);
}
KCALLPROFOFF(57);
}
void PostBoostCrit2(LPCRIT pcrit) {
PTHREAD pth;
BYTE prio;
KCALLPROFON(60);
if (pCurThread->bWaitState == WAITSTATE_PROCESSING) {
pth = HandleToThread((HANDLE)((DWORD)pcrit->lpcs->OwnerThread & ~1));
DEBUGCHK(pth);
if (pcrit->pProxList && ((prio = pcrit->pProxList->prio) < GET_CPRIO(pth))) {
BoostCPrio(pth,prio);
CELOG_SystemInvert(pth->hTh, prio);
}
}
KCALLPROFOFF(60);
}
void CritFinalBoost(LPCRITICAL_SECTION lpcs) {
LPCRIT pcrit;
DWORD prio;
KCALLPROFON(59);
DEBUGCHK(lpcs->OwnerThread == hCurThread);
pcrit = (LPCRIT)lpcs->hCrit;
if (!pcrit->bListed && pcrit->pProxList)
LinkCritMut(pcrit,pCurThread,1);
if (pcrit->pProxList && ((prio = pcrit->pProxList->prio) < GET_CPRIO(pCurThread))) {
SET_CPRIO(pCurThread,prio);
CELOG_SystemInvert(pCurThread->hTh, prio);
}
KCALLPROFOFF(59);
}
VOID AddToProcRunnable(PPROCESS pproc, PTHREAD pth) {
KCALLPROFON(24);
pth->pNextInProc = pproc->pTh;
pth->pPrevInProc = 0;
DEBUGCHK(!pproc->pTh->pPrevInProc);
pproc->pTh->pPrevInProc = pth;
pproc->pTh = pth;
MakeRun(pth);
KCALLPROFOFF(24);
}
HANDLE WakeOneThreadInterruptDelayed(LPEVENT lpe) {
PTHREAD pth;
LPPROXY pprox;
HANDLE hRet;
pprox = lpe->pProxList;
DEBUGCHK(pprox->pObject == (LPBYTE)lpe);
DEBUGCHK(pprox->bType == HT_MANUALEVENT);
DEBUGCHK(pprox->pQDown == pprox);
DEBUGCHK(pprox->pQPrev == (LPPROXY)lpe);
DEBUGCHK(pprox->dwRetVal == WAIT_OBJECT_0);
lpe->pProxList = 0;
pth = pprox->pTh;
DEBUGCHK(!pth->lpce);
pth->wCount++;
DEBUGCHK(pth->lpProxy == pprox);
pth->lpProxy = 0;
if (pth->bWaitState == WAITSTATE_BLOCKED) {
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_RUNNABLE);
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_RUNNING);
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_NEEDSRUN);
pth->retValue = WAIT_OBJECT_0;
hRet = pth->hTh;
SET_RUNSTATE(pth,RUNSTATE_NEEDSRUN);
} else {
DEBUGCHK(!GET_SLEEPING(pth));
DEBUGCHK(pth->bWaitState == WAITSTATE_PROCESSING);
pth->dwPendReturn = WAIT_OBJECT_0;
pth->bWaitState = WAITSTATE_SIGNALLED;
hRet = 0;
}
return hRet;
}
void WakeOneThreadFlat(LPEVENT pObject, HANDLE *phTh) {
PTHREAD pth;
LPPROXY pprox, pDown;
KCALLPROFON(41);
if (pprox = pObject->pProxList) {
DEBUGCHK((pprox->bType == SH_CURPROC) || (pprox->bType == SH_CURTHREAD) || (pprox->bType == HT_MANUALEVENT));
DEBUGCHK(pprox->pQPrev = (LPPROXY)pObject);
pDown = pprox->pQDown;
DEBUGCHK(pDown);
if (pDown == pprox) { // we're alone
pObject->pProxList = 0;
} else {
pDown->pQUp = pprox->pQUp;
pprox->pQUp->pQDown = pObject->pProxList = pDown;
pDown->pQPrev = (LPPROXY)pObject;
}
pprox->pQDown = 0;
pth = pprox->pTh;
DEBUGCHK(pth);
if (pth->wCount == pprox->wCount) {
DEBUGCHK(pth->lpce);
pth->lpce->base = pth->lpProxy;
pth->lpce->size = (DWORD)pth->lpPendProxy;
pth->lpProxy = 0;
pth->wCount++;
if (pth->bWaitState == WAITSTATE_BLOCKED) {
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_RUNNABLE);
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_RUNNING);
DEBUGCHK(GET_RUNSTATE(pth) != RUNSTATE_NEEDSRUN);
pth->retValue = pprox->dwRetVal;
SET_RUNSTATE(pth,RUNSTATE_NEEDSRUN);
*phTh = pth->hTh;
} else {
DEBUGCHK(!GET_SLEEPING(pth));
DEBUGCHK(pth->bWaitState == WAITSTATE_PROCESSING);
pth->dwPendReturn = pprox->dwRetVal;
pth->bWaitState = WAITSTATE_SIGNALLED;
}
}
}
KCALLPROFOFF(41);
}
DWORD EventModMan(LPEVENT lpe, LPSTUBEVENT lpse, DWORD action) {
DWORD prio;
KCALLPROFON(15);
prio = lpe->bMaxPrio;
lpe->bMaxPrio = THREAD_RT_PRIORITY_IDLE;
if (lpse->pProxList = lpe->pProxList) {
lpse->pProxList->pQPrev = (LPPROXY)lpse;
DEBUGCHK(lpse->pProxList->pQDown);
lpe->pProxList = 0;
}
lpe->state = (action == EVENT_SET);
KCALLPROFOFF(15);
return prio;
}
BOOL EventModAuto(LPEVENT lpe, DWORD action, HANDLE *phTh) {
BOOL bRet;
PTHREAD pth;
LPPROXY pprox, pDown, pNext;
BYTE prio;
KCALLPROFON(16);
bRet = 0;
if (!(pprox = lpe->pProxList))
lpe->state = (action == EVENT_SET);
else {
pDown = pprox->pQDown;
if (lpe->onequeue) {
DEBUGCHK(pprox->pQPrev = (LPPROXY)lpe);
if (pDown == pprox) { // we're alone
lpe->pProxList = 0;
} else {
pDown->pQUp = pprox->pQUp;
pprox->pQUp->pQDown = lpe->pProxList = pDown;
pDown->pQPrev = (LPPROXY)lpe;
}
} else {
prio = pprox->prio/PRIORITY_LEVELS_HASHSCALE;
pNext = pprox->pQNext;
if (lpe->pProxHash[prio] == pprox) {
lpe->pProxHash[prio] = ((pDown != pprox) ? pDown :
(pNext && (pNext->prio/PRIORITY_LEVELS_HASHSCALE == prio)) ? pNext : 0);
}
if (pDown == pprox) {
if (lpe->pProxList = pNext)
pNext->pQPrev = 0;
} else {
pDown->pQUp = pprox->pQUp;
pprox->pQUp->pQDown = pDown;
lpe->pProxList = pDown;
DEBUGCHK(!pDown->pQPrev);
if (pNext) {
pNext->pQPrev = pDown;
pDown->pQNext = pNext;
}
}
}
pprox->pQDown = 0;
pth = pprox->pTh;
DEBUGCHK(pth);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -