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

📄 physmem.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 2 页
字号:
/*		Copyright (c) 1995-2000 Microsoft Corporation.  All rights reserved. */#include "kernel.h"//#define PHYSPAGESTOLEDS 1#ifdef PHYSPAGESTOLEDS#define LogPhysicalPages(PageFreeCount) OEMWriteDebugLED(0,PageFreeCount);#else#define LogPhysicalPages(PageFreeCount) (0)#endif#define STACK_RESERVE		15#define MIN_PROCESS_PAGES   STACK_RESERVE#define PAGEOUT_LOW			(( 68*1024)/PAGE_SIZE)	// do pageout once below this mark, reset when above high#define PAGEOUT_HIGH		((132*1024)/PAGE_SIZE)#define PAGE_OUT_TRIGGER	(( 24*1024)/PAGE_SIZE)	// page out if below highwater and this much paged in recentlyvoid ZeroPage(void *pvPage);BOOL ScavengeStacks(int cNeed);HANDLE GwesOOMEvent;long GwesLowThreshold;long GwesCriticalThreshold;long GwesLowBlockSize;long GwesCriticalBlockSize;LPBYTE pFreeKStacks;extern void FreeSpareBytes(LPBYTE lpb, uint size);extern CRITICAL_SECTION PhysCS;extern PTHREAD pCleanupThread;// PageOutNeeded is set to 1 when the number of free pages drops below// PageOutTrigger and the cleanup thread's event is signalled. When the// cleanup thread starts performing page out, it sets the variable to 2.// When the page free count rises above PageOutLevel, PageOutNeeded is// reset to 0.//// The free page count thresholds are set based upon the Gwes OOM level.long PageOutNeeded;long PageOutTrigger;    // Threshold level to start page out.long PageOutLevel;      // Threshold to stop page out./* GWE calls this function to register an Out Of Memory event, which * HoldPages sets when free physical memory drops below the given threshold. */VOID SC_SetGwesOOMEvent(HANDLE hEvent, DWORD cpLow, DWORD cpCritical,						DWORD cpLowBlockSize, DWORD cpCriticalBlockSize) {	DEBUGMSG(ZONE_ENTRY,(L"SC_SetGwesOOMEvent entry: %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx\r\n",		hEvent,cpLow,cpCritical,cpLowBlockSize,cpCriticalBlockSize));	GwesOOMEvent = hEvent;	GwesLowThreshold = cpLow;	GwesCriticalThreshold = cpCritical;	GwesLowBlockSize = cpLowBlockSize;	GwesCriticalBlockSize = cpCriticalBlockSize;	PageOutLevel = GwesLowThreshold + PAGEOUT_HIGH;	PageOutTrigger = GwesLowThreshold + PAGEOUT_LOW;	DEBUGMSG(ZONE_ENTRY,(L"SC_SetGwesOOMEvent exit\r\n"));}#if PAGE_SIZE < 2048void UnlinkPhysPage(LPBYTE pMem) {	KCALLPROFON(38);	if (*(DWORD *)((DWORD)pMem + 0x20000000))		*(LPBYTE *)(*(DWORD *)((DWORD)pMem + 0x20000000) + 0x20000004) =			*(LPBYTE *)((DWORD)pMem + 0x20000004);	if (*(DWORD *)((DWORD)pMem + 0x20000004))		*(LPBYTE *)(*(DWORD *)((DWORD)pMem + 0x20000004) + 0x20000000) =			*(LPBYTE *)((DWORD)pMem + 0x20000000);	else		LogPtr->pKList = *(LPBYTE *)((DWORD)pMem + 0x20000000);	*(LPDWORD)(pMem + 0x20000000) = 0;	*(LPDWORD)(pMem + 0x20000004) = 0;	KCALLPROFOFF(38);}#endifvoid LinkPhysPage(LPBYTE pMem) {	KCALLPROFON(32);	*(LPBYTE *)((DWORD)pMem + 0x20000000) = LogPtr->pKList;	*(LPBYTE *)((DWORD)pMem + 0x20000004) = 0;	if (LogPtr->pKList)		*(LPBYTE *)((DWORD)LogPtr->pKList + 0x20000004) = pMem;	LogPtr->pKList = pMem;    PageFreeCount++;	LogPhysicalPages(PageFreeCount);	KCALLPROFOFF(32);}LPBYTE GrabFirstPhysPage(DWORD dwCount) {	PFREEINFO pfi;    uint ix;    PHYSICAL_ADDRESS paRet;	LPBYTE pMem;	KCALLPROFON(33);	if (pMem = LogPtr->pKList) {		paRet = GetPFN(pMem);		if (LogPtr->pKList = *(LPBYTE *)((DWORD)pMem + 0x20000000))			*(LPBYTE *)((DWORD)LogPtr->pKList + 0x20000004) = 0;		*(LPDWORD)(pMem + 0x20000000) = 0;		*(LPDWORD)(pMem + 0x20000004) = 0;		pfi = GetRegionFromAddr(paRet);		ix = (paRet - pfi->paStart) / PFN_INCR;	    DEBUGCHK(pfi->pUseMap[ix] == 0);	    DEBUGCHK(dwCount && (dwCount <= 0xff));		pfi->pUseMap[ix] = (BYTE)dwCount;	    PageFreeCount--;		LogPhysicalPages(PageFreeCount);		DEBUGCHK(PageFreeCount >= 0);	}	DEBUGCHK(pMem);	KCALLPROFOFF(33);	return pMem;	}// called by loader.c when moving memory "slider"void RemovePage(DWORD dwAddr) {	DWORD pfn, ix;	FREEINFO *pfi;	pfn = GetPFN(dwAddr);	pfi = GetRegionFromAddr(pfn);	DEBUGCHK(pfi);    ix = (pfn - pfi->paStart) / PFN_INCR;    pfi->pUseMap[ix] = 0xff;}BOOL DemandCommit(ulong addr) {	MEMBLOCK *pmb;	LPDWORD pPage;	PFREEINFO pfi;   	uint ix;	PHYSICAL_ADDRESS paRet;	LPBYTE pMem;	pmb = (*SectionTable[addr>>VA_SECTION])[(addr>>VA_BLOCK) & BLOCK_MASK];		if (!*(pPage = &pmb->aPages[(addr>>VA_PAGE) & PAGE_MASK])) {		pMem = LogPtr->pKList;		if (GwesOOMEvent && (PageFreeCount < GwesCriticalThreshold)) {			SetEvent(GwesOOMEvent);		}        		if (!PageFreeCount || !pMem) {			RETAILMSG(1,(L"--->>> DemandCommit: FATAL ERROR!  COMPLETELY OUT OF MEMORY (%8.8lx %8.8lx)!\r\n",pMem,PageFreeCount));			INTERRUPTS_OFF();            while (1) {                // we don't recover if there's no memory, so better off to just stop            }			return FALSE;		}		paRet = GetPFN(pMem);		pMem = (LPBYTE)((DWORD)pMem + 0x20000000);		if (LogPtr->pKList = *(LPBYTE *)pMem)			*(LPBYTE *)((DWORD)LogPtr->pKList + 0x20000004) = 0;		*(LPDWORD)pMem = 0;		*(LPDWORD)(pMem + 4) = 0;		pfi = GetRegionFromAddr(paRet);		ix = (paRet - pfi->paStart) / PFN_INCR;    	DEBUGCHK(!pfi->pUseMap[ix]);		pfi->pUseMap[ix] = 1;		*pPage = paRet | PG_READ_WRITE;    	PageFreeCount--;		LogPhysicalPages(PageFreeCount);		DEBUGCHK(PageFreeCount >= 0);		return TRUE;	}	return FALSE;}void EnterPhysCS(void) {    LPVOID pMem;	EnterCriticalSection(&PhysCS);	DEBUGCHK(PhysCS.OwnerThread == hCurThread);	if (PhysCS.LockCount == 1)	    while (pMem = InterlockedPopList(&pFreeKStacks))			FreeHelperStack(pMem);}BOOL SC_GiveKPhys(void *ptr, ulong length) {	BOOL bRet = FALSE;	LPBYTE pPage;	DWORD loop;	PFREEINFO pfi;	PHYSICAL_ADDRESS paPFN;	uint ix;	if (pCurProc->bTrustLevel != KERN_TRUST_FULL) {	    KSetLastError(pCurThread, ERROR_ACCESS_DENIED);    	return 0;	}	DEBUGMSG(ZONE_ENTRY,(L"SC_GiveKPhys entry: %8.8lx %8.8lx\r\n",ptr,length));	SC_CacheSync(CACHE_SYNC_DISCARD);	EnterPhysCS();	for (loop = 0; loop < length; loop++) {		pPage = *((LPBYTE *)ptr+loop);		ZeroPage(pPage + 0x20000000);		paPFN = GetPFN(pPage);		pfi = GetRegionFromAddr(paPFN);		DEBUGCHK(pfi);        ix = (paPFN - pfi->paStart) / PFN_INCR;        DEBUGCHK(pfi->pUseMap[ix] == 0xff);        pfi->pUseMap[ix] = 0;		KCall((PKFN)LinkPhysPage,pPage);    }	KInfoTable[KINX_NUMPAGES] += length;    // If there are enough free pages, clear the PageOutNeeded flag.    if (PageFreeCount > PageOutLevel)        PageOutNeeded = 0;	bRet = TRUE;	LeaveCriticalSection(&PhysCS);	DEBUGMSG(ZONE_ENTRY,(L"SC_GiveKPhys exit: %8.8lx\r\n",bRet));	return bRet;}BOOL SC_GetKPhys(void *ptr, ulong length) {	LPVOID *pPages;	BOOL bRet = FALSE;    DWORD dwCount;    LPBYTE pMem;	DEBUGMSG(ZONE_ENTRY,(L"SC_GetKPhys entry: %8.8lx %8.8lx\r\n",ptr,length));	if (pCurProc->bTrustLevel != KERN_TRUST_FULL) {	    KSetLastError(pCurThread, ERROR_ACCESS_DENIED);    	return 0;	}	pPages = (LPVOID *)ptr;	EnterPhysCS();	ScavengeStacks(100000);     // Reclaim all extra stack pages.	if ((length == 1) || ((DWORD)PageFreeCount > length + PageOutTrigger)) {		for (dwCount = length; dwCount; dwCount--) {			if (!(pMem = (LPBYTE)KCall((PKFN)GrabFirstPhysPage,0xff))) {				LeaveCriticalSection(&PhysCS);				SC_GiveKPhys(ptr,length - dwCount);				DEBUGCHK(0);				RETAILMSG(1,(L"Error getting pages!\r\n"));				return 0;			}			KInfoTable[KINX_NUMPAGES]--;			*pPages++ = pMem;	    }	    bRet = TRUE;	}	LeaveCriticalSection(&PhysCS);	DEBUGMSG(ZONE_ENTRY,(L"SC_GetKPhys exit: %8.8lx\r\n",bRet));	return bRet;}	void InitMemoryPool() {	PFREEINFO pfi, pfiEnd;	DWORD loop;	LPBYTE pPage;	/* Fill in data fields in user visible kernel data page */	KInfoTable[KINX_PROCARRAY] = (long)ProcArray;	KInfoTable[KINX_PAGESIZE] = PAGE_SIZE;#ifdef PFN_SHIFT	KInfoTable[KINX_PFN_SHIFT] = PFN_SHIFT;#endif	KInfoTable[KINX_PFN_MASK] = (DWORD)PFNfromEntry(~0);	KInfoTable[KINX_SECTIONS] = (long)SectionTable;	KInfoTable[KINX_MEMINFO] = (long)&MemoryInfo;	KInfoTable[KINX_KDATA_ADDR] = (long)&KData;	SC_CacheSync(CACHE_SYNC_DISCARD);	for (pfi = MemoryInfo.pFi, pfiEnd = pfi+MemoryInfo.cFi ; pfi < pfiEnd ; ++pfi) {		DEBUGMSG(ZONE_MEMORY, (TEXT("InitMemoryPool: Init range: map=%8.8lx start=%8.8lx end=%8.8lx\r\n"),				pfi->pUseMap, pfi->paStart, pfi->paEnd));		pPage = 0;		for (loop = pfi->paStart; loop < pfi->paEnd; loop += PFN_INCR) {			if (!pfi->pUseMap[(loop-pfi->paStart)/PFN_INCR]) {				pPage = Phys2Virt(loop);				ZeroPage(pPage + 0x20000000);				LinkPhysPage(pPage);				LogPtr->pKList = pPage;	    	    KInfoTable[KINX_NUMPAGES]++;			}		}	}    DEBUGMSG(ZONE_MEMORY,(TEXT("InitMemoryPool done, free=%d\r\n"),PageFreeCount));}PTHREAD PthScavTarget;PPROCESS PprcScavTarget = &ProcArray[0];int StackScavCount;HTHREAD ScavengeOnePage(void) {	HTHREAD ret;	KCALLPROFON(13);    if (!PthScavTarget) {	    if (++PprcScavTarget >= &ProcArray[MAX_PROCESSES])			PprcScavTarget = ProcArray;	   	++StackScavCount;	    if (!PprcScavTarget->dwVMBase || !(PthScavTarget = PprcScavTarget->pTh)) {

⌨️ 快捷键说明

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