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

📄 schedule.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    if (pDown = pth->pDownSleep) {
        DEBUGCHK (!GET_NEEDSLEEP(pDown) && GET_SLEEPING (pDown));
#ifdef DEBUG
        if (cprio > GET_CPRIO (pDown)) {
            DEBUGMSG (1, (L"pth->bprio = %d, pth->cprio = %d, pDown->bprio = %d, pDown->cprio = %d\r\n",
                pth->bBPrio, cprio, pDown->bBPrio, GET_CPRIO(pDown)));
            if (pth->pOwnedList) {
                DEBUGMSG (1, (L"pth->pOwnedList->bListedPrio = %dlx\r\n", pth->pOwnedList->bListedPrio));
            }
            if (pDown->pOwnedList) {
                DEBUGMSG (1, (L"pDown->pOwnedList->bListedPrio = %dlx\r\n", pDown->pOwnedList->bListedPrio));
            }
            DEBUGMSG (1, (L"pth->wInfo = %8.8lx, pDown->wInfo = %8.8lx\r\n", pth->wInfo, pDown->wInfo));
            DEBUGCHK (0);
        }
#endif
        DEBUGCHK (!pDown->bSuspendCnt);
        pDown->wCount ++;
        pDown->wCount2 ++;
        CLEAR_SLEEPING (pDown);
        pDown->pUpSleep = pth->pDownSleep = 0;
        // don't worry about it if NEEDRUN flag is set
        if (GET_RUNSTATE(pDown) != RUNSTATE_NEEDSRUN) {

            // setup proxy for cleanup if not pure sleeping 
            DEBUGCHK(GET_RUNSTATE(pDown) == RUNSTATE_BLOCKED);
            if (pDown->lpce) { // not set if purely sleeping
                pDown->lpce->base = pDown->lpProxy;
                pDown->lpce->size = (DWORD)pDown->lpPendProxy;
                pDown->lpProxy = 0;
            } else if (pDown->lpProxy) {
                // must be an interrupt event - special case it!
                LPPROXY pprox = pDown->lpProxy;
                LPEVENT lpe = (LPEVENT)pprox->pObject;
                DEBUGCHK(pprox->bType == HT_MANUALEVENT);
                DEBUGCHK(pprox->pQDown == pprox);
                DEBUGCHK(pprox->pQPrev == (LPPROXY)lpe);
                DEBUGCHK(pprox->dwRetVal == WAIT_OBJECT_0);
                lpe->pProxList = 0;
                pprox->pQDown = 0;
                pDown->lpProxy = 0;
            }

            // replace pth's slot if of same priority
            if (cprio == GET_CPRIO (pDown)) {
                if (pth == pth->pDownRun) {
                    // only node in this priority
                    pDown->pUpRun = pDown->pDownRun = pDown;
                } else {
                    // fixup the links
                    if (pDown->pUpRun = pth->pUpRun)
                        pDown->pUpRun->pDownRun = pDown;
                    if (pDown->pDownRun = pth->pDownRun)
                        pDown->pDownRun->pUpRun = pDown;
                }
                // fix up next node
                if (pDown->pNextSleepRun = pth->pNextSleepRun)
                    pDown->pNextSleepRun->pPrevSleepRun = pDown;

                // fix up prev node, update pRunnable if necessary
                if (pDown->pPrevSleepRun = pth->pPrevSleepRun) {
                    pDown->pPrevSleepRun->pNextSleepRun = pDown;
                } else if (RunList.pRunnable == pth) {
                    RunList.pRunnable = pDown;
                }
                // update hash table if necessary
                if (RunList.pHashThread[prio] == pth)
                    RunList.pHashThread[prio] = pDown;
                SET_RUNSTATE (pDown, RUNSTATE_RUNNABLE);
                return;
            }
            // not of the same priority, just call MakeRun
            // might want to save an instruction or two by
            // handling the logic here (don't have to check
            // suspend/pRunnable, etc.
            MakeRun (pDown);
        } 
    }

    // remove pth from the run queue
    pDown = pth->pDownRun;
    pNext = pth->pNextSleepRun;
    if (RunList.pHashThread[prio] == pth) {
        RunList.pHashThread[prio] = ((pDown != pth) ? pDown :
            (pNext && (GET_CPRIO(pNext)/PRIORITY_LEVELS_HASHSCALE == (WORD)prio)) ? pNext : 0);
    }
    if (pDown == pth) {
        if (!pth->pPrevSleepRun) {
            DEBUGCHK(RunList.pRunnable == pth);
            if (RunList.pRunnable = pNext)
                pNext->pPrevSleepRun = 0;
        } else {
            if (pth->pPrevSleepRun->pNextSleepRun = pNext)
                pNext->pPrevSleepRun = pth->pPrevSleepRun;
        }
    } else {
        pDown->pUpRun = pth->pUpRun;
        pth->pUpRun->pDownRun = pDown;
        if (pth->pPrevSleepRun) {
            pth->pPrevSleepRun->pNextSleepRun = pDown;
            pDown->pPrevSleepRun = pth->pPrevSleepRun;
            goto FinishDequeue;
        } else if (pth == RunList.pRunnable) {
            RunList.pRunnable = pDown;
            DEBUGCHK(!pDown->pPrevSleepRun);
FinishDequeue:            
            if (pNext) {
                pNext->pPrevSleepRun = pDown;
                pDown->pNextSleepRun = pNext;
            }
        }
    }
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
SleepqDequeue(
    PTHREAD pth
    ) 
{
    PTHREAD pth2;
    DEBUGCHK(pth && GET_SLEEPING(pth));
    pth->wCount2++;

    if (pth2 = pth->pUpSleep) {
        DEBUGCHK (pth != SleepList);
        DEBUGCHK (!pth->pNextSleepRun && !pth->pPrevSleepRun);
        if (pth2->pDownSleep = pth->pDownSleep) {
            pth2->pDownSleep->pUpSleep = pth2;
            pth->pDownSleep = 0;
        }
        pth->pUpSleep = 0;
    } else if (pth2 = pth->pDownSleep) {
        DEBUGCHK (!pth2->pNextSleepRun && !pth2->pPrevSleepRun);
        if (pth2->pNextSleepRun = pth->pNextSleepRun) {
            pth2->pNextSleepRun->pPrevSleepRun = pth2;
        }
        if (pth2->pPrevSleepRun = pth->pPrevSleepRun) {
            pth2->pPrevSleepRun->pNextSleepRun = pth2;
        } else {
            DEBUGCHK (pth == SleepList);
            SleepList = pth2;
        }
        pth2->pUpSleep = pth->pDownSleep = 0;

    } else if (pth2 = pth->pPrevSleepRun) {
        if (pth2->pNextSleepRun = pth->pNextSleepRun) {
            pth2->pNextSleepRun->pPrevSleepRun = pth2;
        }
    } else {
        DEBUGCHK (pth == SleepList);
        // update SleepList
        if (SleepList = pth->pNextSleepRun) {
            SleepList->pPrevSleepRun = 0;
        }
    }

    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);
            pth->wCount ++;
        }
        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);
    } else if (GET_SLEEPING (pth) && pth->pUpSleep && (GET_RUNSTATE(pth) != RUNSTATE_NEEDSRUN)) {
        SleepqDequeue (pth);
        SET_NEEDSLEEP (pth);
        if (pth->lpce) {
            pth->bWaitState = WAITSTATE_PROCESSING; // re-process the wait
        }
        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);
            if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {
                CELOG_SystemInvert(pth->hTh, prio);
            }
        }
        if (!GET_NOPRIOCALC(pth))
            LaterLinkMutOwner(lpm);
        ReprioCritMut((LPCRIT)lpm,pth);
    }
    KCALLPROFOFF(56);
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 

⌨️ 快捷键说明

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