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

📄 virtmem.c

📁 wince下的源代码集合打包
💻 C
📖 第 1 页 / 共 5 页
字号:
        }        DEBUGMSG(ZONE_VIRTMEM, (TEXT("Reserved %d pages @%8.8lx\r\n"), cPages, lpvAddress));        if (cNeed) {            /* Set unused entries to BAD_PAGE */            DEBUGMSG(ZONE_VIRTMEM, (TEXT("Reserved %d extra pages.\r\n"), -cNeed));            cNeed += PAGES_PER_BLOCK;            for (ix = cNeed ; ix < PAGES_PER_BLOCK ; ++ix)                pmb->aPages[ix] = BAD_PAGE;        }        /* If not committing pages, then return the address of the         * reserved region */        if (!(fdwAllocationType & MEM_COMMIT)) {            LeaveCriticalSection(&VAcs);            ERRORMSG(!lpvAddress,(L"Failed VirtualAlloc/reserve of %8.8lx bytes\r\n",cbSize));            CELOG_VirtualAlloc((DWORD)lpvAddress, (DWORD)lpvAddress, cbSize, fdwAllocationType, fdwProtect);            return lpvAddress;        }    } else {        /* Not reserving memory, so must be committing. Verify that the         * requested region is within range and within an existing reserved         * memory region that the client is allowed to access.         */        if (cbSize > (1<<VA_SECTION))        	goto invalidParm;        if (!(fdwAllocationType & MEM_COMMIT) || lpvAddress == 0)            goto invalidParm;        if ((ulong)lpvAddress>>VA_SECTION > SECTION_MASK)            goto invalidParm;        pscn = SectionTable[((ulong)lpvAddress>>VA_SECTION) & SECTION_MASK];        if (pscn == NULL_SECTION)            goto invalidParm;        ixBlock = ((ulong)lpvAddress >> VA_BLOCK) & BLOCK_MASK;        /* Adjust lpvAddress to PAGE boundary and calculate the number         * of pages to commit. */        lpvAddress = (LPVOID)((ulong)lpvAddress & ~(PAGE_SIZE-1));        cPages = (ulong)(lpbEnd - (LPBYTE)lpvAddress + PAGE_SIZE-1) / PAGE_SIZE;        /* locate the starting block of the region */        if ((ixFirB = FindFirstBlock(pscn, ixBlock)) == UNKNOWN_BASE)            goto invalidParm;    }    /* Verify that cPages of memory starting with the first page indicated by     * lpvAddress can be committed within the region.     *     *  (pscn) = ptr to section array     *  (ixBlock) = index of block containing the first page to commit     *  (cPages) = # of pages to commit     */    ixPage = ((ulong)lpvAddress >> VA_PAGE) & PAGE_MASK;    cpAlloc = ScanRegion(pscn, ixFirB, ixBlock, ixPage, cPages, 0);    if (cpAlloc == -1)        goto cleanUp;    /* Commit cPages of memory starting with the first page indicated by     * lpvAddress. Allocate all required pages before any changes to the     * virtual region are performed.     *     *  (pscn) = ptr to section array     *  (ixBlock) = index of block containing the first page to commit     *  (cPages) = # of pages to commit     *  (cpAlloc) = # of physical pages required     */    DEBUGMSG(ZONE_VIRTMEM, (TEXT("Allocating %d pages.\r\n"), cpAlloc));    if (!HoldPages(cpAlloc, FALSE)) {        err = ERROR_NOT_ENOUGH_MEMORY;        goto setError;    }	ixBlock = (ixBlock*PAGES_PER_BLOCK+ixPage+cPages-1)/PAGES_PER_BLOCK;	ix = ((ixPage + cPages - 1) % PAGES_PER_BLOCK) + 1;    /* Walk the page tables to map in the physical pages. */    for (; cPages ; --ixBlock) {        pmb = (*pscn)[ixBlock];        for (; cPages && ix-- > 0 ; --cPages) {            if (pmb->aPages[ix] == 0) {            	DWORD dwRetries;            	for (dwRetries = 0; (dwRetries < 20) && !(ulPFN = GetHeldPage()); dwRetries++)            		Sleep(100);            	if (ulPFN) {	                DEBUGMSG(ZONE_VIRTMEM, (TEXT("Mapping %8.8lx @%3.3x%x000 perm=%x\r\n"),    	                    ulPFN, ixBlock, ix, ulPgMask));        	        pmb->aPages[ix] = ulPFN | ulPgMask;        	    } else {			    	InterlockedIncrement(&PageFreeCount);					RETAILMSG(1,(L"--->>> VirtualAlloc: FATAL ERROR!  COMPLETELY OUT OF MEMORY (%8.8lx)!\r\n",PageFreeCount));				}            } else                pmb->aPages[ix] = (pmb->aPages[ix] & ~PG_PERMISSION_MASK) | ulPgMask;        }        ix = PAGES_PER_BLOCK;            /* start with last page of previous block */    }    InvalidateRange(lpvAddress, cbSize); // in case we changed permissions above    LeaveCriticalSection(&VAcs);    ERRORMSG(!lpvAddress,(L"Failed VirtualAlloc(%8.8lx) of %8.8lx bytes\r\n",fdwAllocationType,cbSize));        CELOG_VirtualAlloc((DWORD)lpvAddress, (DWORD)lpvAddress, cbSize, fdwAllocationType, fdwProtect);    return lpvAddress;    /* There was an error reserving or commiting a range of pages. If reserving     * pages, release any pages which were reserved before the failure occured.     */invalidParm:    err = ERROR_INVALID_PARAMETER;setError:    DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualAlloc failed. error=%d\r\n"), err));    KSetLastError(pCurThread, err);cleanUp:    if (fdwAllocationType & MEM_RESERVE && ixFirB != UNKNOWN_BASE) {        /* Remove the reservation */        ReleaseRegion(pscn, ixFirB);    }    LeaveCriticalSection(&VAcs);    ERRORMSG(!lpvAddress,(L"Failed VirtualAlloc(%8.8lx) of %8.8lx bytes\r\n",fdwAllocationType,cbSize));    return 0;}BOOL SC_VirtualFree(LPVOID lpvAddress,  /* address of region of committed pages */DWORD cbSize,       /* size of the region */DWORD fdwFreeType)  /* type of free operation */{    int ixBlock;    int ixPage;    int ixFirB;         /* index of first block in region */    PSECTION pscn;    int cpReserved;     /* # of reserved (not commited) pages in region */    int cpRegion;       /* total # of pages in region */    int cPages;         /* # of pages to free */    DWORD baseScn;		/* base address of section */    BOOL bForceDecommit;    /* Verify that the requested region is within range and within an     * existing reserved memory region that the client is allowed to     * access and locate the starting block of the region.     */    bForceDecommit = (fdwFreeType & 0x80000000);    fdwFreeType &= ~0x80000000;    CELOG_VirtualFree((DWORD)lpvAddress, cbSize, fdwFreeType);    DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualFree @%8.8lx size=%lx freetype=%lx\r\n"),            lpvAddress, cbSize, fdwFreeType));    if (((DWORD)lpvAddress >= FIRST_MAPPER_ADDRESS) && !cbSize && (fdwFreeType == MEM_RELEASE)) {	    DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualFree @%8.8lx size=%lx freetype=%lx : doing HugeVirtualRelease\r\n"),            lpvAddress, cbSize, fdwFreeType));		return HugeVirtualRelease(lpvAddress);    }    /* Lockout other changes to the virtual memory state. */    EnterCriticalSection(&VAcs);    if (lpvAddress == 0 || (ulong)lpvAddress>>VA_SECTION > SECTION_MASK)        goto invalidParm;    pscn = SectionTable[((ulong)lpvAddress>>VA_SECTION) & SECTION_MASK];    if (pscn == NULL_SECTION)        goto invalidParm;    baseScn = (DWORD)lpvAddress & (SECTION_MASK<<VA_SECTION);    ixBlock = ((ulong)lpvAddress >> VA_BLOCK) & BLOCK_MASK;    if ((ixFirB = FindFirstBlock(pscn, ixBlock)) == UNKNOWN_BASE)        goto invalidParm;    /* Verify the status of the region based upon the type of free operation     * being performed.     *     *  (pscn) = ptr to section array     *  (ixBlock) = index of block containing the first page of lpvAddress     *  (ixFirB) = index of first block in the region     */    ixPage = ((ulong)lpvAddress >> VA_PAGE) & PAGE_MASK;    if (fdwFreeType == MEM_RELEASE) {        DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualFree releasing region ixBlock=%x.\r\n"),ixBlock));        if (cbSize != 0 || ixPage != 0 || ixBlock != ixFirB)            goto invalidParm;        cpReserved = ScanRegion(pscn, ixFirB, ixFirB, 0, (BLOCK_MASK+1)*PAGES_PER_BLOCK, &cpRegion);        DEBUGCHK(cpReserved != -1);        DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualFree: cpReserved=%d cpRegion=%d\r\n"), cpReserved, cpRegion));        /* The entire region must be either reserved or commited. */        if (cpReserved != cpRegion) {            if (cpReserved != 0)                goto invalidParm;            DecommitPages(pscn, ixFirB, 0, cpRegion, baseScn, bForceDecommit);        }        ReleaseRegion(pscn, ixFirB);        LeaveCriticalSection(&VAcs);        return TRUE;    } else if (fdwFreeType == MEM_DECOMMIT) {        DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualFree decommitting block %x page %x.\r\n"), ixBlock, ixPage));        if (cbSize == 0)            goto invalidParm;        cPages = (((ulong)lpvAddress + cbSize + PAGE_SIZE-1) / PAGE_SIZE)                - ((ulong)lpvAddress / PAGE_SIZE);        cpReserved = ScanRegion(pscn, ixFirB, ixBlock, ixPage, cPages, &cpRegion);        if (cpRegion < cPages)            goto invalidParm;        if (cpReserved != cPages)            DecommitPages(pscn, ixBlock, ixPage, cPages, baseScn, bForceDecommit);        LeaveCriticalSection(&VAcs);        return TRUE;    }invalidParm:    LeaveCriticalSection(&VAcs);    DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualFree failed.\r\n")));    KSetLastError(pCurThread, ERROR_INVALID_PARAMETER);    return FALSE;}/*	@doc INTERNAL	@func BOOL | VirtualCopy | Duplicate a virtual memory range (Windows CE Only)	@parm LPVOID | lpvDest | address of destination pages 	@parm LPVOID | lpvSrc | address of source pages     @parm DWORD | cbSize | number of bytes to copy     @parm DWORD | fdwProtect) | access protection for destination pages 	@comm Description unavailable at this time.*/BOOL DoVirtualCopy(LPVOID lpvDest,         /* address of destination pages */LPVOID lpvSrc,          /* address of source pages */DWORD cbSize,           /* # of bytes to copy */DWORD fdwProtect)       /* access protection for destination pages */{    int ixDestBlk, ixSrcBlk;    int ixPage;    int ixDestFirB;     /* index of first block in destination region */    int ixSrcFirB;      /* index of first block in destination region */    PSECTION pscnDest;    PSECTION pscnSrc;    int cpReserved;     /* # of reserved (not commited) pages in region */    int cpRegion;       /* total # of pages in region */    int cPages;         /* # of pages to copy */    ulong ulPFN;        /* page physical frame number */    ulong ulPgMask;    BOOL bPhys = FALSE; /* TRUE if mapping physical pages */    /* Verify that the requested regions are within range and within     * existing reserved memory regions that the client is allowed to     * access and locate the starting block of both regions.     */    CELOG_VirtualCopy((DWORD)lpvDest, (DWORD)lpvSrc, cbSize, fdwProtect);    DEBUGMSG(ZONE_VIRTMEM, (TEXT("VirtualCopy %8.8lx <= %8.8lx size=%lx prot=%lx\r\n"),            lpvDest, lpvSrc, cbSize, fdwProtect));    if (fdwProtect & PAGE_PHYSICAL) {        bPhys = TRUE;        fdwProtect &= ~PAGE_PHYSICAL;    }    if ((ulPgMask = MakePagePerms(fdwProtect)) == 0)        return FALSE;   /* invalid protection flags, error # already set */    /* Lockout other changes to the virtual memory state. */    EnterCriticalSection(&VAcs);    /* Validate the destination parameters */    if (!cbSize || !lpvDest || (ulong)lpvDest>>VA_SECTION > SECTION_MASK)        goto invalidParm;    pscnDest = SectionTable[((ulong)lpvDest>>VA_SECTION) & SECTION_MASK];    if (pscnDest == NULL_SECTION)        goto invalidParm;    ixDestBlk = ((ulong)lpvDest >> VA_BLOCK) & BLOCK_MASK;    ixDestFirB = FindFirstBlock(pscnDest, ixDestBlk);    if (ixDestFirB == UNKNOWN_BASE)        goto invalidParm;    /* Verify that all of the destination pages are reserved (not committed). */    ixPage = ((ulong)lpvDest >> VA_PAGE) & PAGE_MASK;    cPages = (((ulong)lpvDest + cbSize + PAGE_SIZE-1) / PAGE_SIZE) - ((ulong)lpvDest / PAGE_SIZE);    cpReserved = ScanRegion(pscnDest, ixDestFirB, ixDestBlk, ixPage, cPages, 0);    if (cpReserved != cPages)        goto invalidParm;    /* Validate the source address parameters */    if (bPhys) {        ulPFN = PFNfrom256(lpvSrc);        if (((ulong)lpvDest&(PAGE_SIZE-1)) != ((ulong)lpvSrc<<8 &(PAGE_SIZE-1)))            goto invalidParm;    } else if ((ulong)lpvSrc>>VA_SECTION > SECTION_MASK) {        /* Mapping pages from a physical region. */        bPhys = TRUE;        ulPFN = GetPFN(lpvSrc);        if (((ulong)lpvDest&(PAGE_SIZE-1)) != ((ulong)lpvSrc&(PAGE_SIZE-1)))            goto invalidParm;    } else {        /* Mapping pages from another virtual region. */        bPhys = FALSE;        if (lpvSrc == 0 || ((ulong)lpvDest&0xFFFFL) != ((ulong)lpvSrc&0xFFFFL))            goto invalidParm;        pscnSrc = SectionTable[((ulong)lpvSrc>>VA_SECTION) & SECTION_MASK];        if (pscnSrc == NULL_SECTION)            goto invalidParm;        ixSrcBlk = ((ulong)lpvSrc >> VA_BLOCK) & BLOCK_MASK;        ixSrcFirB = FindFirstBlock(pscnSrc, ixSrcBlk);        if (ixSrcFirB == UNKNOWN_BASE)            goto invalidParm;        /* Verify that all of the source pages are committed */        cpReserved = ScanRegion(pscnSrc, ixSrcFirB, ixSrcBlk, ixPage, cPages, &cpRegion);        if (cpReserved || cpRegion != cPages)            goto invalidParm;    }    /* Walk the the page tables mapping the pages in the source region into     * the destination region. */    for (; cPages > 0 ; ++ixDestBlk, ++ixSrcBlk) {        MEMBLOCK *pmbSrc;        MEMBLOCK *pmbDest = (*pscnDest)[ixDestBlk];        if (!bPhys)            pmbSrc = (*pscnSrc)[ixSrcBlk];        if (!bPhys && ixDestFirB == ixSrcFirB && ixPage == 0                && (cPages >= PAGES_PER_BLOCK                || pmbSrc->aPages[cPages] == BAD_PAGE)                && (pmbSrc->aPages[0]&PG_PERMISSION_MASK) == ulPgMask) {            /* Copying an entire block with the same access permissions into             * the same offset within the two sections.  Share the same MEMBLOCK             * by bumping the use count on the MEMBLOCK. */            DEBUGCHK(pmbDest != NULL_BLOCK && pmbDest != RESERVED_BLOCK);            FreeMem(pmbDest,HEAP_MEMBLOCK);            ++pmbSrc->cUses;            AddAccess(&pmbSrc->alk, pCurProc->aky);            (*pscnDest)[ixDestBlk] = pmbSrc;            cPages -= PAGES_PER_BLOCK;#if defined(SH4) && (PAGE_SIZE==4096)        } else if (bPhys && !ixPage && !(ixDestBlk & 15) && !(ulPFN&1048575) && (cPages >= 256)) {			int loop, loop2;			DWORD dwSetting = ulPgMask | PG_1M_MASK;			for (loop = 0; loop < 16; loop++) {				pmbDest = (*pscnDest)[ixDestBlk+loop];				for (loop2 = 0; loop2 < 16; loop2++) {		        	pmbDest->aPages[loop2] = dwSetting | ulPFN;   			        ulPFN = NextPFN(ulPFN);   			    }   			}			cPages-=256;			ixDestBlk+=15;#endif						} else {            for ( ; cPages && ixPage < PAGES_PER_BLOCK ; ++ixPage, --cPages) {                if (bPhys) {                    DEBUGMSG(ZONE_VIRTMEM,                        (TEXT("Mapping physical page %8.8lx @%3.3x%x000 perm=%x\r\n"),                        ulPFN, ixDestBlk, ixPage, ulPgMask));#if 0#if defined(SH3) && (PAGE_SIZE==1024)					if (!(ixPage&3) && !(ulPFN&4095) && (cPages >= 4)) {						int loop;

⌨️ 快捷键说明

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