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

📄 physmem.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 2 页
字号:
	    	KCALLPROFOFF(13);	    	return 0;	    }	    if (PthScavTarget == pCurThread)	    	PthScavTarget = pCurThread->pNextInProc;	    KCALLPROFOFF(13);	    return 0;    }    if (HandleToThread(PthScavTarget->hTh) != PthScavTarget) {	    PthScavTarget = 0;    	KCALLPROFOFF(13);    	return 0;    }    ret = ((pCurThread != PthScavTarget) && MDTestStack(PthScavTarget)) ? PthScavTarget->hTh : 0;    if ((PthScavTarget = PthScavTarget->pNextInProc) == pCurThread)    	PthScavTarget = pCurThread->pNextInProc;	KCALLPROFOFF(13);    return ret;}HANDLE hCurrScav;BOOL ScavengeStacks(int cNeed) {    HTHREAD hth;    PTHREAD pth;	ulong addr, pages, base;    ulong pte;    int ixPage, ixBlock;    PSECTION pscn;    MEMBLOCK *pmb;    ACCESSKEY ulOldKey;    DEBUGMSG(ZONE_MEMORY, (TEXT("Scavenging stacks for %d pages.\r\n"), cNeed-PageFreeCount));    StackScavCount = 0;    SWITCHKEY(ulOldKey,0xffffffff);    while ((StackScavCount <= MAX_PROCESSES) && (cNeed > PageFreeCount)) {    	if (hth = (HTHREAD)KCall((PKFN)ScavengeOnePage)) {        	if (SuspendThread(hth) != -1) {        		hCurrScav = hth;        		pages = 0;        		pth = HandleToThread(hth);				SC_CacheSync(CACHE_SYNC_DISCARD);				while (addr = MDTestStack(pth)) {				    pscn = SectionTable[addr>>VA_SECTION];				    ixBlock = (addr>>VA_BLOCK) & BLOCK_MASK;				    ixPage = (addr>>VA_PAGE) & PAGE_MASK;				    if ((pmb = (*pscn)[ixBlock]) == NULL_BLOCK || pmb == RESERVED_BLOCK ||						!(pmb->flags&MB_FLAG_AUTOCOMMIT) || pmb == PmbDecommitting ||						!(pte = pmb->aPages[ixPage]) || pte == BAD_PAGE)						break;			        pmb->aPages[ixPage] = 0;		            MDShrinkStack(pth);					FreePhysPage(PFNfromEntry(pte));		            DEBUGCHK(!pages || (base == addr - PAGE_SIZE));		            base = addr;		            pages++;				}				if (pages)		            InvalidateRange((PVOID)base, PAGE_SIZE*pages);        		hCurrScav = 0;				ResumeThread(hth);			}		}	}	SETCURKEY(ulOldKey);	return (StackScavCount > MAX_PROCESSES) ? FALSE : TRUE;}PHYSICAL_ADDRESS GetHeldPage(void) {    PHYSICAL_ADDRESS paRet;	LPBYTE pMem;	if (pMem = (LPBYTE)KCall((PKFN)GrabFirstPhysPage,1)) {	    PageFreeCount++; // since we already reserved it		LogPhysicalPages(PageFreeCount);		paRet = GetPFN(pMem);	} else		paRet = 0;	DEBUGMSG(ZONE_PHYSMEM,(TEXT("GetHeldPage: Returning %8.8lx\r\n"), paRet));    return paRet;}BOOL HoldPages(int cpNeed, BOOL bForce) {	BOOL fSetGweOomEvent = FALSE;	BOOL bRet = FALSE;	WORD prio;    EnterPhysCS();    // Check if this request will drop the page free count below the    // page out trigger and signal the clean up thread to start doing    // pageouts if so.    if ((cpNeed+PageOutTrigger > PageFreeCount) &&    	(!PageOutNeeded || (PagedInCount > PAGE_OUT_TRIGGER))) {        PageOutNeeded = 1;        PagedInCount = 0;        if (prio = GET_CPRIO(pCurThread))        	prio--;        if (prio < GET_CPRIO(pCleanupThread))	        KCall((PKFN)SetThreadBasePrio, pCleanupThread->hTh, (DWORD)prio);	    SetEvent(hAlarmThreadWakeup);    }    do {        if (cpNeed+GwesLowThreshold <= PageFreeCount) {        	DWORD pfc;        	do {				pfc = PageFreeCount;			} while (InterlockedTestExchange(&PageFreeCount,pfc,pfc-cpNeed) != (LONG)pfc);			LogPhysicalPages(PageFreeCount);			bRet = TRUE;			goto hpDone;        }    } while (ScavengeStacks(cpNeed+GwesLowThreshold));	// Even after scavenging stacks, we were unable to satisfy the request	// without going below the GWE low threshold.	// Do not allow a request of size GwesLowBlockSize to succeed if	// doing so would leave less than the low threshold.  Same with	// GwesCriticalBlockSize and GwesCriticalThreshold.	if (bForce || !((cpNeed > GwesLowBlockSize	        && cpNeed+GwesLowThreshold > PageFreeCount)		    || (cpNeed > GwesCriticalBlockSize		    && cpNeed + GwesCriticalThreshold > PageFreeCount))) {      	// Memory is low. Notify GWE, so that GWE can ask    	// the user to close some apps.    	if (GwesOOMEvent &&			((PageFreeCount >= GwesLowThreshold) ||			 ((PageFreeCount < cpNeed + GwesCriticalThreshold))))           	fSetGweOomEvent = TRUE;                if ((cpNeed + (bForce?0:STACK_RESERVE)) <= PageFreeCount) {        	DWORD pfc;        	do {				pfc = PageFreeCount;			} while (InterlockedTestExchange(&PageFreeCount,pfc,pfc-cpNeed) != (LONG)pfc);			LogPhysicalPages(PageFreeCount);        	bRet = TRUE;        }	}hpDone:    LeaveCriticalSection(&PhysCS);	if (fSetGweOomEvent)		SetEvent(GwesOOMEvent);    return bRet;}void DupPhysPage(PHYSICAL_ADDRESS paPFN) {	PFREEINFO pfi;    uint ix;    //NOTE: DupPhysage and FreePhysPage are only called by the virtual memory    // system with the VA critical section held so DupPhysPage does not need to    // claim the physical memory critical section because it does not change    // the page free count.	if ((pfi = GetRegionFromAddr(paPFN)) != 0) {        ix = (paPFN - pfi->paStart) / PFN_INCR;        DEBUGCHK(pfi->pUseMap[ix] != 0);        DEBUGMSG(ZONE_PHYSMEM, (TEXT("DupPhysPage: PFN=%8.8lx ix=%x rc=%d\r\n"), paPFN,                ix, pfi->pUseMap[ix]));        ++pfi->pUseMap[ix];    }}void FreePhysPage(PHYSICAL_ADDRESS paPFN) {	PFREEINFO pfi;	uint ix;	if ((pfi = GetRegionFromAddr(paPFN)) != 0) {        ix = (paPFN - pfi->paStart) / PFN_INCR;        DEBUGMSG(ZONE_PHYSMEM, (TEXT("FreePhysPage: PFN=%8.8lx ix=%x rc=%d\r\n"), paPFN,                ix, pfi->pUseMap[ix]));        EnterPhysCS();        DEBUGCHK(pfi->pUseMap[ix] != 0);        if ((pfi->pUseMap[ix] != 0xff) && (!--pfi->pUseMap[ix])) {            DEBUGMSG(ZONE_PHYSMEM, (TEXT("FreePhysPage: PFN=%8.8lx\r\n"), paPFN));            ZeroPage((LPBYTE)Phys2Virt(paPFN)+0x20000000);            KCall((PKFN)LinkPhysPage,Phys2Virt(paPFN));            // If there are enough free pages, clear the PageOutNeeded flag.            if (PageFreeCount > PageOutLevel)                PageOutNeeded = 0;        }        LeaveCriticalSection(&PhysCS);    }}ERRFALSE(sizeof(SECTION) == 2048);#if PAGE_SIZE == 4096PSECTION GetSection(void){	PHYSICAL_ADDRESS pAddr;    if ((PageFreeCount > 1+MIN_PROCESS_PAGES) && HoldPages(1, FALSE)) {    	if (pAddr = GetHeldPage()) {			InterlockedIncrement(&KInfoTable[KINX_SYSPAGES]);    	    return Phys2Virt(pAddr); // can't put GetHeldPage, since Phys2Virt's a macro!    	}    	InterlockedIncrement(&PageFreeCount);    }    return 0;}void FreeSection(PSECTION pscn) {	SC_CacheSync(CACHE_SYNC_DISCARD);    FreePhysPage(GetPFN(pscn));	InterlockedDecrement(&KInfoTable[KINX_SYSPAGES]);}LPVOID GetHelperStack(void) {	return AllocMem(HEAP_HLPRSTK);//	return GetSection();}void FreeHelperStack(LPVOID pMem) {	FreeMem(pMem,HEAP_HLPRSTK);//	FreeSection(pMem);}#elseERRFALSE((sizeof(SECTION)+PAGE_SIZE-1)/PAGE_SIZE == 2);void FreeSection(PSECTION pscn) {    PHYSICAL_ADDRESS paSect;    paSect = GetPFN(pscn);	SC_CacheSync(CACHE_SYNC_DISCARD);    FreePhysPage(paSect);    FreePhysPage(NextPFN(paSect));	InterlockedDecrement(&KInfoTable[KINX_SYSPAGES]);	InterlockedDecrement(&KInfoTable[KINX_SYSPAGES]);}LPBYTE TakeTwoPages(PFREEINFO pfi, uint ix, LPBYTE pMem) {	KCALLPROFON(40);	if (pfi->pUseMap[ix] || pfi->pUseMap[ix+1]) {		KCALLPROFOFF(40);		return 0;	}	pfi->pUseMap[ix] = 1;    pfi->pUseMap[ix+1] = 1;    UnlinkPhysPage(pMem);    UnlinkPhysPage(pMem+PAGE_SIZE);	KCALLPROFOFF(40);    return pMem;}PSECTION GetSection(void) {	PFREEINFO pfi, pfiEnd;    uint ix;    PHYSICAL_ADDRESS paSect;    PSECTION pscn = 0;    LPVOID pMem;    while (pMem = InterlockedPopList(&pFreeKStacks))		FreeHelperStack(pMem);    if ((PageFreeCount > 2+MIN_PROCESS_PAGES) && HoldPages(2, FALSE)) {    	pfi = &MemoryInfo.pFi[0];   	    for (pfi = &MemoryInfo.pFi[0], pfiEnd = pfi+MemoryInfo.cFi ; pfi < pfiEnd ; ++pfi) {	   		paSect = pfi->paEnd - 2 * PFN_INCR;	   	    ix = (paSect - pfi->paStart) / PFN_INCR;	   	    while (paSect >= pfi->paStart) {    			if (pscn = (PSECTION)KCall((PKFN)TakeTwoPages,pfi,ix,Phys2Virt(paSect))) {        			InterlockedIncrement(&KInfoTable[KINX_SYSPAGES]);        			InterlockedIncrement(&KInfoTable[KINX_SYSPAGES]);        			goto foundPages;        		}				ix--;				paSect -= PFN_INCR;	   	    }		}		InterlockedIncrement(&PageFreeCount);		InterlockedIncrement(&PageFreeCount);	}foundPages:	DEBUGMSG(ZONE_PHYSMEM,(TEXT("GetSection: Returning %8.8lx\r\n"), pscn));    return pscn;}LPVOID GetHelperStack(void) {	PHYSICAL_ADDRESS pAddr;    if (HoldPages(1, FALSE)) {    	if (pAddr = GetHeldPage()) {			InterlockedIncrement(&KInfoTable[KINX_SYSPAGES]);    		return Phys2Virt(pAddr); // can't put GetHeldPage, since Phys2Virt's a macro!    	}    	InterlockedIncrement(&PageFreeCount);    }    return 0;}void FreeHelperStack(LPVOID pMem) {	SC_CacheSync(CACHE_SYNC_DISCARD);    FreePhysPage(GetPFN(pMem));	InterlockedDecrement(&KInfoTable[KINX_SYSPAGES]);}#endif

⌨️ 快捷键说明

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