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

📄 schedule.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 5 页
字号:
		if (pth->wCount != pprox->wCount)
			bRet = 1;
		else {
			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;
			}
			lpe->state = 0;
		}
	}
	KCALLPROFOFF(16);
	return bRet;
}

void DoFreeMutex(LPMUTEX lpm) {
	KCALLPROFON(34);
	UnlinkCritMut((LPCRIT)lpm,lpm->pOwner);
	KCALLPROFOFF(34);
}
void DoFreeCrit(LPCRIT lpcrit) {
	PTHREAD pth;
	KCALLPROFON(45);
	if (lpcrit->bListed == 1) {
		pth = HandleToThread(lpcrit->lpcs->OwnerThread);
		DEBUGCHK(pth);
		UnlinkCritMut(lpcrit,pth);
	}
	KCALLPROFOFF(45);
}

/* When a thread tries to closehandle an event */

BOOL SC_EventCloseHandle(HANDLE hEvent) {
	HANDLE hTrav;
	LPEVENT lpe, lpe2;
	DEBUGMSG(ZONE_ENTRY,(L"SC_EventCloseHandle entry: %8.8lx\r\n",hEvent));
   CELOG_EventCloseHandle(hEvent);
	if (DecRef(hEvent,pCurProc,FALSE)) {
      CELOG_EventDelete(hEvent);
		EnterCriticalSection(&NameCS);
		lpe = HandleToEvent(hEvent);
		DEBUGCHK(lpe);
		if (hEvent == hEventList)
			hEventList = lpe->hNext;
		else {
			hTrav = hEventList;
			lpe2 = HandleToEvent(hTrav);
			DEBUGCHK(lpe2);
			while (lpe2->hNext != hEvent) {
				hTrav = lpe2->hNext;
				lpe2 = HandleToEvent(hTrav);
				DEBUGCHK(lpe2);
			}
			lpe2->hNext = lpe->hNext;
		}
		LeaveCriticalSection(&NameCS);
		if (lpe->onequeue) {
			while (lpe->pProxList)
				KCall((PKFN)DequeueFlatProxy,lpe->pProxList);
		} else {
			while (lpe->pProxList)
				KCall((PKFN)DequeuePrioProxy,lpe->pProxList);
		}
		if (lpe->name)
			FreeName(lpe->name);
		if (lpe->pIntrProxy)
	    	FreeIntrFromEvent(lpe);
		FreeMem((LPVOID)lpe,HEAP_EVENT);
		FreeHandle(hEvent);
	}
   DEBUGMSG(ZONE_ENTRY,(L"SC_EventCloseHandle exit: %8.8lx\r\n",TRUE));
	return TRUE;
}

/* When a thread tries to closehandle a semaphore */

BOOL SC_SemCloseHandle(HANDLE hSem) {
	HANDLE hTrav;
	LPSEMAPHORE lpsem, lpsem2;
	DEBUGMSG(ZONE_ENTRY,(L"SC_SemCloseHandle entry: %8.8lx\r\n",hSem));
   CELOG_SemaphoreCloseHandle(hSem);
	if (DecRef(hSem,pCurProc,FALSE)) {
      CELOG_SemaphoreDelete(hSem);
		EnterCriticalSection(&NameCS);
		lpsem = HandleToSem(hSem);
		DEBUGCHK(lpsem);
		if (hSem == hSemList)
			hSemList = lpsem->hNext;
		else {
			hTrav = hSemList;
			lpsem2 = HandleToSem(hTrav);
			DEBUGCHK(lpsem2);
			while (lpsem2->hNext != hSem) {
				hTrav = lpsem2->hNext;
				lpsem2 = HandleToSem(hTrav);
				DEBUGCHK(lpsem2);
			}
			lpsem2->hNext = lpsem->hNext;
		}
		LeaveCriticalSection(&NameCS);
		while (lpsem->pProxList)
			KCall((PKFN)DequeuePrioProxy,lpsem->pProxList);
		if (lpsem->name)
			FreeName(lpsem->name);
		FreeMem((LPVOID)lpsem,HEAP_SEMAPHORE);
		FreeHandle(hSem);
	}
   DEBUGMSG(ZONE_ENTRY,(L"SC_SemCloseHandle exit: %8.8lx\r\n",TRUE));
	return TRUE;
}

/* When a thread tries to closehandle a mutex */

BOOL SC_MutexCloseHandle(HANDLE hMutex) {
	HANDLE hTrav;
	LPMUTEX lpmutex, lpmutex2;
	DEBUGMSG(ZONE_ENTRY,(L"SC_MutexCloseHandle entry: %8.8lx\r\n",hMutex));
   CELOG_MutexCloseHandle(hMutex);
	EnterCriticalSection(&NameCS);
	if (DecRef(hMutex,pCurProc,FALSE)) {
      CELOG_MutexDelete(hMutex);
		lpmutex = HandleToMutex(hMutex);
		DEBUGCHK(lpmutex);
		if (hMutex == hMutexList)
			hMutexList = lpmutex->hNext;
		else {
			hTrav = hMutexList;
			lpmutex2 = HandleToMutex(hTrav);
			DEBUGCHK(lpmutex2);
			while (lpmutex2->hNext != hMutex) {
				hTrav = lpmutex2->hNext;
				lpmutex2 = HandleToMutex(hTrav);
				DEBUGCHK(lpmutex2);
			}
			lpmutex2->hNext = lpmutex->hNext;
		}
		while (lpmutex->pProxList)
			if (KCall((PKFN)DequeuePrioProxy,lpmutex->pProxList))
				KCall((PKFN)DoReprioMutex,lpmutex);
		KCall((PKFN)DoFreeMutex,lpmutex);
		if (lpmutex->name)
			FreeName(lpmutex->name);
		FreeMem((LPVOID)lpmutex,HEAP_MUTEX);
		FreeHandle(hMutex);
	}
	LeaveCriticalSection(&NameCS);
	DEBUGMSG(ZONE_ENTRY,(L"SC_MutexCloseHandle exit: %8.8lx\r\n",TRUE));
	return TRUE;
}

BOOL SC_EventAddAccess(HANDLE hEvent) {
	BOOL retval;
	DEBUGMSG(ZONE_ENTRY,(L"SC_EventAddAccess entry: %8.8lx\r\n",hEvent));
	if (pCurProc->bTrustLevel != KERN_TRUST_FULL) {
		ERRORMSG(1,(L"SC_EventAddAccess failed due to insufficient trust\r\n"));
		retval = FALSE;
	} else
		retval = IncRef(hEvent,pCurProc);
	DEBUGMSG(ZONE_ENTRY,(L"SC_EventAddAccess exit: %d\r\n",retval));
	return retval;
}

HANDLE EventModIntr(LPEVENT lpe, DWORD type) {
	HANDLE hRet;
	KCALLPROFON(42);
	if (!lpe->pProxList) {
		lpe->state = (type == EVENT_SET);
		hRet = 0;
	} else {
		lpe->state = 0;
		hRet = WakeOneThreadInterruptDelayed(lpe);
	}
	DEBUGCHK(!lpe->manualreset);
	KCALLPROFOFF(42);
	return hRet;
}

void AdjustPrioDown() {
    DWORD dwPrio, dwPrio2;
    KCALLPROFON(66);
    dwPrio = GET_BPRIO(pCurThread);
    if (pCurThread->pOwnedList && ((dwPrio2 = pCurThread->pOwnedList->bListedPrio) < dwPrio))
        dwPrio = dwPrio2;
    SET_CPRIO(pCurThread,dwPrio);
    if (RunList.pRunnable && (dwPrio > GET_CPRIO(RunList.pRunnable)))
        SetReschedule();
    KCALLPROFOFF(66);
}

/* When a thread tries to set/reset/pulse an event */

BOOL SC_EventModify(HANDLE hEvent, DWORD type) {
	LPEVENT lpe;
	HANDLE hWake;
	LPSTUBEVENT lpse;
	DEBUGMSG(ZONE_ENTRY,(L"SC_EventModify entry: %8.8lx %8.8lx\r\n",hEvent,type));
	if (!(lpe = (bAllKMode ? HandleToEventPerm(hEvent) : HandleToEvent(hEvent)))) {
        KSetLastError(pCurThread, ERROR_INVALID_HANDLE);
		return FALSE;
	}
	
   CELOG_Event(hEvent, type);

   switch (type) {
		case EVENT_PULSE:
		case EVENT_SET:
			
         if (lpe->pIntrProxy) {
				DEBUGCHK(lpe->onequeue);
				if (hWake = (HANDLE)KCall((PKFN)EventModIntr,lpe,type))
					KCall((PKFN)MakeRunIfNeeded,hWake);
			} else if (lpe->manualreset) {
				DWORD dwOldPrio, dwNewPrio;
				DEBUGCHK(lpe->onequeue);
				// *lpse can't be stack-based since other threads won't have access and might dequeue/requeue
				if (!(lpse = AllocMem(HEAP_STUBEVENT))) {
					DEBUGMSG(ZONE_ENTRY,(L"SC_EventModify exit: %8.8lx\r\n",FALSE));
					KSetLastError(pCurThread,ERROR_OUTOFMEMORY);
					return FALSE;
				}
				dwOldPrio = GET_BPRIO(pCurThread);
				dwNewPrio = KCall((PKFN)EventModMan,lpe,lpse,type);
				if (lpse->pProxList) {
					SET_NOPRIOCALC(pCurThread);
					if (dwNewPrio < dwOldPrio)
						SET_CPRIO(pCurThread,dwNewPrio);
					while (lpse->pProxList) {
						hWake = 0;
						KCall((PKFN)WakeOneThreadFlat,lpse,&hWake);
						if (hWake)
							KCall((PKFN)MakeRunIfNeeded,hWake);
					}
					CLEAR_NOPRIOCALC(pCurThread);
					if (dwNewPrio < dwOldPrio)
						KCall((PKFN)AdjustPrioDown);
				}
				FreeMem(lpse,HEAP_STUBEVENT);
			} else {
				hWake = 0;
				while (KCall((PKFN)EventModAuto,lpe,type,&hWake))
					;
				if (hWake)
					KCall((PKFN)MakeRunIfNeeded,hWake);
			}
			break;
		case EVENT_RESET:
         lpe->state = 0;
			break;
		default:
			DEBUGCHK(0);
	}
	DEBUGMSG(ZONE_ENTRY,(L"SC_EventModify exit: %8.8lx\r\n",TRUE));
	return TRUE;
}

BOOL IsValidIntrEvent(HANDLE hEvent) {
	EVENT *lpe;
	if (!(lpe = HandleToEvent(hEvent)) || lpe->manualreset || lpe->pProxList)
		return FALSE;
	return TRUE;
}

/* When a thread tries to create an event */

HANDLE SC_CreateEvent(LPSECURITY_ATTRIBUTES lpsa, BOOL fManReset, BOOL fInitState, LPCWSTR lpEventName) {
	HANDLE hEvent;
	LPEVENT lpe;
	int len;
	DEBUGMSG(ZONE_ENTRY,(L"SC_CreateEvent entry: %8.8lx %8.8lx %8.8lx %8.8lx\r\n",
		lpsa,fManReset,fInitState,lpEventName));
	if (lpEventName) {
		len = strlenW(lpEventName) + 1;
		if (len > MAX_PATH) {
			KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
			DEBUGMSG(ZONE_ENTRY,(L"SC_CreateEvent exit: %8.8lx\r\n",0));
			return 0;
		}
		len *= sizeof(WCHAR);
		LockPages(lpEventName,len,0,LOCKFLAG_READ);
	}
	EnterCriticalSection(&NameCS);
	if (lpEventName) {
		for (hEvent = hEventList; hEvent; hEvent = lpe->hNext) {
			lpe = HandleToEvent(hEvent);
			DEBUGCHK(lpe);
			if (lpe->name && !strcmpW(lpe->name->name,lpEventName)) {
				IncRef(hEvent,pCurProc);
				KSetLastError(pCurThread,ERROR_ALREADY_EXISTS);
				goto exit;
			}
		}
		KSetLastError(pCurThread,0);
	}
	if (!(lpe = (LPEVENT)AllocMem(HEAP_EVENT))) {
		KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
		hEvent = 0;
		goto exit;
	}
	if (!(hEvent = AllocHandle(&cinfEvent,lpe,pCurProc))) {
		KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
		FreeMem(lpe,HEAP_EVENT);
		hEvent = 0;
		goto exit;
	}
	if (lpEventName) {
		if (!(lpe->name = (Name *)AllocName(len))) {
			KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
			FreeHandle(hEvent);
			FreeMem(lpe,HEAP_EVENT);
			hEvent = 0;
			goto exit;
		}
		memcpy(lpe->name->name,lpEventName,len);
	} else
		lpe->name = 0;
	memset(lpe->pProxHash,0,sizeof(lpe->pProxHash));
	lpe->pProxList = 0;
	lpe->hNext = hEventList;
	hEventList = hEvent;
	lpe->state = fInitState;
	lpe->manualreset = fManReset;
	lpe->onequeue = fManReset;
	lpe->pIntrProxy = 0;
	lpe->bMaxPrio = THREAD_RT_PRIORITY_IDLE;
exit:
	CELOG_EventCreate(hEvent, fManReset, fInitState, lpEventName);
	LeaveCriticalSection(&NameCS);
	if (lpEventName)
		UnlockPages(lpEventName,len);
	DEBUGMSG(ZONE_ENTRY,(L"SC_CreateEvent exit: %8.8lx\r\n",hEvent));
	return hEvent;
}

/* When a thread tries to create a semaphore */

HANDLE SC_CreateSemaphore(LPSECURITY_ATTRIBUTES lpsa, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName) {
	HANDLE hSem;
	int len;
	LPSEMAPHORE lpsem;
	DEBUGMSG(ZONE_ENTRY,(L"SC_CreateSemaphore entry: %8.8lx %8.8lx %8.8lx %8.8lx\r\n",lpsa,lInitialCount,lMaximumCount,lpName));
	if (lpName) {
		len = strlenW(lpName) + 1;
		if (len > MAX_PATH) {
			KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
			DEBUGMSG(ZONE_ENTRY,(L"SC_CreateSemaphore exit: %8.8lx\r\n",0));
			return 0;
		}
		len *= sizeof(WCHAR);
		LockPages(lpName,len,0,LOCKFLAG_READ);
	}
	EnterCriticalSection(&NameCS);
	if (lpName) {
		for (hSem = hSemList; hSem; hSem = lpsem->hNext) {
			lpsem = HandleToSem(hSem);
			DEBUGCHK(lpsem);
			if (lpsem->name && !strcmpW(lpsem->name->name,lpName)) {
				IncRef(hSem,pCurProc);
				KSetLastError(pCurThread,ERROR_ALREADY_EXISTS);
				goto exit;
			}
		}
		KSetLastError(pCurThread,0);
	}
	if ((lInitialCount < 0) || (lMaximumCount <= 0) || lpsa || (lInitialCount > lMaximumCount)) {
		KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
		hSem = 0;
		goto exit;
	}
	if (!(lpsem = (LPSEMAPHORE)AllocMem(HEAP_SEMAPHORE))) {
		KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
		hSem = 0;
		goto exit;
	}
	if (!(hSem = AllocHandle(&cinfSem,lpsem,pCurProc))) {
		KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
		FreeMem(lpsem,HEAP_SEMAPHORE);
		hSem = 0;
		goto exit;
	}
	if (lpName) {
		if (!(lpsem->name = (Name *)AllocName(len))) {
			KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
			FreeHandle(hSem);
			FreeMem(lpsem,HEAP_SEMAPHORE);
			hSem = 0;
			goto exit;
		}
		memcpy(lpsem->name->name,lpName,len);
	} else
		lpsem->name = 0;
	memset(lpsem->pProxHash,0,sizeof(lpsem->pProxHash));
	lpsem->pProxList = 0;
	lpsem->hNext = hSemList;
	hSemList = hSem;
	lpsem->lCount = lInitialCount;
	lpsem->lMaxCount = lMaximumCount;
	lpsem->lPending = 0;
exit:
	CELOG_SemaphoreCreate(hSem, lInitialCount, lMaximumCount, lpName);
	LeaveCriticalSection(&NameCS);
	if (lpName)
		UnlockPages(lpName,len);
	DEBUGMSG(ZONE_ENTRY,(L"SC_CreateSemaphore exit: %8.8lx\r\n",hSem));
	return hSem;
}

/* When a thread tries to create a mutex */

HANDLE SC_CreateMutex(LPSECURITY_ATTRIBUTES lpsa, BOOL bInitialOwner, LPCTSTR lpName) {
	int len;
	HANDLE hMutex;
	LPMUTEX lpmutex;
	DEBUGMSG(ZONE_ENTRY,(L"SC_CreateMutex entry: %8.8lx %8.8lx %8.8lx\r\n",lpsa,bInitialOwner,lpName));
	if (lpName) {
		len = strlenW(lpName) + 1;
		if (len > MAX_PATH) {
			KSetLastError(pCurThread,ERROR_INVALID_PARAMETER);
			DEBUGMSG(ZONE_ENTRY,(L"SC_CreateMutex exit: %8.8lx\r\n",0));
			return 0;
		}
		len *= sizeof(WCHAR);

⌨️ 快捷键说明

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