Exemple #1
0
/*
 * Return the address of the base of the newly committed memory, or 0
 * if committing failed.
 */
void *
sysCommitMem(void *requestedAddr, size_t requestedSize, size_t *committedSize)
{
    void *committedAddr;
    char *ret;

    *committedSize = roundUpToGrain(requestedSize);
    committedAddr = (void *) roundDownToGrain((long) requestedAddr);
#ifdef USE_MALLOC
#ifdef __linux__
    ret = committedAddr;
#else
    ret = requestedAddr;
#endif
#else
    ret = mapChunkReserve(committedAddr, *committedSize);
#endif
    if (ret) {
        committedAddr = ret;
        Log4(2,
    "sysCommitMem: 0x%x bytes at 0x%x (request: 0x%x bytes at 0x%x)\n",
             *committedSize, committedAddr, requestedSize, requestedAddr);
    } else {
        committedAddr = 0;
        Log2(2, "sysCommitMem failed: (request: 0x%x bytes at 0x%x)\n",
             requestedSize, requestedAddr);
    }

    return committedAddr;
}
/* Purpose: Decommits a range of memory which was previously committed using
            CVMmemCommit().  The memory range may be a subset of the range
	    returned by CVMmemCommit().  The range to decommit is specified by
            addr as the starting address of the range, and requestedSize as the
	    size of the range in units of bytes.
   Returns: The starting address of the decommitted range is returned.
            The actual size of the decommitted range is set in *decommittedSize
	    in units of bytes.
	    Else, if failed to decommit, NULL is returned and *decommittedSize
	    is set to 0.
   Note: memory sizes must be in increments of the page size as returned
         by CVMmemPageSize() in units of bytes.
	 Committed memory must be uncommitted using CVMmemDecommit() before it
	 is unmmapped with CVMmemUnmap().  If this order is not adhered to,
	 then the state of the committed memory will be undefined.
*/
void *CVMmemDecommit(void *requestedAddr, size_t requestedSize,
		     size_t *decommittedSize)
{
    void *decommittedAddr = NULL;
    CVMBool success = CVM_FALSE;

    CVMassert(requestedSize == roundDownToGrain(requestedSize));
    CVMassert(requestedAddr == (void *)roundUpToGrain((CVMAddr)requestedAddr));

    if (requestedSize != 0) {
        success = VirtualFree(requestedAddr, requestedSize, MEM_DECOMMIT);
#ifdef WINCE
        if (!success && ((DWORD)requestedAddr + requestedSize) >=
            ROUND_UP_32MB(requestedAddr)) {
            /* crossing 32MB boundary, need to break up the decommit */
            size_t origSize = requestedSize;
            void *newAddr = requestedAddr;

            while(((DWORD)newAddr + origSize) >= ROUND_UP_32MB(newAddr)) {
                size_t newSize = ROUND_UP_32MB(newAddr) - (DWORD)newAddr;
                success = VirtualFree(newAddr, newSize, MEM_DECOMMIT);
                if (!success) {
                    break;
                }
                newAddr = (void*)((DWORD)newAddr + newSize);
                origSize -= newSize;
            }

            if (success && origSize > 0) {
                /* Some residual pages to decommit */
                success = VirtualFree(newAddr, origSize, MEM_DECOMMIT);
            }
        }
#endif
    }
    if (success) {
	decommittedAddr = requestedAddr;
	*decommittedSize = requestedSize;
    } else {
	*decommittedSize = 0;
    }

#ifdef DEBUG_MMAP
    if (success) {
	CVMconsolePrintf(
            "CVMmemDecommit: 0x%x bytes at 0x%x (request: 0x%x bytes at 0x%x)\n",
            *decommittedSize, decommittedAddr, requestedSize, requestedAddr);
    } else {
	CVMconsolePrintf(
	    "CVMmemDecommit failed: (request: 0x%x bytes at 0x%x)\n",
	    requestedSize, requestedAddr);
    }
#endif

    return decommittedAddr;
}
Exemple #3
0
/*
 * Return the address of the base of the newly decommitted memory, or 0
 * if decommitting failed.
 */
void *
sysDecommitMem(void *requestedAddr, size_t requestedSize,
               size_t *decommittedSize)
{
    void *decommittedAddr;
    char *ret;

    *decommittedSize = roundDownToGrain(requestedSize);
    decommittedAddr = (void *) roundUpToGrain((long) requestedAddr);
#ifdef USE_MALLOC
    ret = 0;
#else
    ret = mapChunkNoreserve(decommittedAddr, *decommittedSize);
#endif
    Log4(2,
         "sysDecommitMem: 0x%x bytes at 0x%x (request: 0x%x bytes at 0x%x)\n",
         *decommittedSize, decommittedAddr, requestedSize, requestedAddr);

    return ret;
}
/* Purpose: Commits a range of memory which was previously reserved using
            CVMmemMap().  The memory range may be a subset of the range
	    returned by CVMmemMap().  The range to commit is specified by
            addr as the starting address of the range, and requestedSize as the
	    size of the range in units of bytes.
   Returns: The starting address of the committed range is returned.
            The actual size of the committed range is set in *committedSize
	    in units of bytes.
	    Else, if failed to commit, NULL is returned and *committedSize is
	    set to 0.
   Note: memory sizes must be in increments of the page size as returned
         by CVMmemPageSize() in units of bytes.
	 Committed memory must be uncommitted using CVMmemDecommit() before it
	 is unmmapped with CVMmemUnmap().  If this order is not adhered to,
	 then the state of the committed memory will be undefined.
*/
void *CVMmemCommit(void *requestedAddr, size_t requestedSize,
		   size_t *committedSize)
{
    void *committedAddr = NULL;
    MEMORY_BASIC_INFORMATION mb;

    CVMassert(requestedSize == roundUpToGrain(requestedSize));
    CVMassert(requestedAddr ==
	      (void *)roundDownToGrain((CVMAddr)requestedAddr));

    if (requestedSize != 0) {
        committedAddr = VirtualAlloc(requestedAddr, requestedSize, MEM_COMMIT,
                                     PAGE_READWRITE);
#ifdef WINCE
        if (committedAddr == NULL && ((DWORD)requestedAddr + requestedSize) >=
            ROUND_UP_32MB(requestedAddr)) {
            /* hitting/crossing 32MB boundary, need to break up the commit */
            size_t origSize = requestedSize;
            void *newAddr = requestedAddr;
            size_t pageSize = CVMmemPageSize();

            while(((DWORD)newAddr + origSize) >= ROUND_UP_32MB(newAddr)) {
                size_t newSize = ROUND_UP_32MB(newAddr) - (DWORD)newAddr;
                if (newSize >= pageSize * 2) {
                    /* Sometimes, for whatever reason, if you
                     * allocate right up to the 32MB boundary it returns
                     * INVALID PARAMETER error. So, back off a page 
                     */
                    newSize -= pageSize;
                }
                committedAddr = VirtualAlloc(newAddr, newSize, MEM_COMMIT,
                                             PAGE_READWRITE);
                if (committedAddr == NULL) {
                    break;
                }
                newAddr = (void*)((DWORD)newAddr + newSize);
                origSize -= newSize;
            }

#if _WIN32_WCE < 600
            while(committedAddr != NULL && origSize > 0) {
                /* Some residual pages to commit */
                /* WinCE < 6.0 fails on commits that are too big, where too big
                 * is some unknown value I can't seem to pin down. So just do
                 * it a page at a time.
                 */
                committedAddr = VirtualAlloc(newAddr, pageSize, MEM_COMMIT,
                                             PAGE_READWRITE);
                origSize -= pageSize;
                newAddr = (void *)((DWORD)newAddr + pageSize);
            }
#else
            if (committedAddr != NULL) {
                committedAddr = VirtualAlloc(newAddr, origSize, MEM_COMMIT,
                                             PAGE_READWRITE);
            }
#endif
            if (committedAddr != NULL) {
                committedAddr = requestedAddr;
            }
        }
#endif
    }
    *committedSize = (committedAddr != NULL) ?
	(CVMassert(committedAddr == requestedAddr), requestedSize) : 0;

#ifdef WINCE
    if (committedAddr == NULL) {
        /* Must have had an error committing, attempt to decommit anything we
         * committed
         */
        size_t decommittedSize;
        CVMmemDecommit(requestedAddr, requestedSize, &decommittedSize);
    }
#endif
#ifdef DEBUG_MMAP
    if (committedAddr != NULL) {
	CVMconsolePrintf(
	    "CVMmemCommit: 0x%x bytes at 0x%x (request: 0x%x bytes at 0x%x)\n",
	    *committedSize, committedAddr, requestedSize, requestedAddr);
    } else {
	CVMconsolePrintf(
	    "CVMmemCommit failed: Error %d, (request: 0x%x bytes at 0x%x)\n",
	    GetLastError(), requestedSize, requestedAddr);
        CVMconsolePrintf("CVMmemCommit: State:\n");
        VirtualQuery(requestedAddr, &mb, sizeof(mb));
        CVMconsolePrintf("  Base: 0x%x\n  AllocBase: 0x%x\n  AllocProtect: 0x%x\n  Size: 0x%x\n  State: 0x%x\n  Protect: 0x%x\n  Type: 0x%x\n",
                         (int)mb.BaseAddress, mb.AllocationBase,
                         mb.AllocationProtect, mb.RegionSize, mb.State,
                         mb.Protect, mb.Type);
    }
#endif

    return committedAddr;
}