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

📄 schedule.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 5 页
字号:
		}
	}
}

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 + -