Ignore:
Timestamp:
Jul 15, 2002, 4:28:53 PM (23 years ago)
Author:
sandervl
Message:

Rewrote algorithm for 64kb alignment in VirtualAlloc'ed memory; allocation changes for heap (in 64kb chunks) & PE image (align at 64kb)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/oslibmem.cpp

    r8866 r8877  
    1 /* $Id: oslibmem.cpp,v 1.2 2002-07-13 16:30:40 sandervl Exp $ */
     1/* $Id: oslibmem.cpp,v 1.3 2002-07-15 14:28:52 sandervl Exp $ */
    22/*
    33 * Wrappers for OS/2 Dos* API
     
    3535#include "initterm.h"
    3636#include "oslibdos.h"
     37#include "oslibmem.h"
    3738#include "dosqss.h"
    3839#include "win32k.h"
     
    5657    rc = DosQueryMem(pb, &size, &attr);
    5758    if(rc) {
    58         dprintf(("OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
     59        dprintf(("!ERROR!: OSLibDosAliasMem: DosQueryMem %x %x return %d", pb, size, rc));
    5960        return rc;
    6061    }
     
    6263    size+= PAGE_SIZE;
    6364    if(size != cb) {
    64         dprintf(("ERROR: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
     65        dprintf(("!WARNING!: OSLibDosAliasMem: size != cb (%x!=%x)!!!!!!!!", size, cb));
    6566        //ignore this and continue return 5;
    6667        attr = fl; //just use original protection flags (NOT CORRECT)
     
    7071        rc = DosSetMem(pb, size, fl);
    7172        if(rc) {
    72                 dprintf(("OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
     73                dprintf(("!ERROR!: OSLibDosAliasMem: DosSetMem %x %x return %d", pb, size, rc));
    7374                attr = fl;
    7475                //just continue for now
     
    7879    rc = DosAliasMem(pb, cb, ppbAlias, 2);
    7980    if(rc) {
    80         dprintf(("OSLibDosAliasMem: DosAliasMem %x %x returned %d", pb, cb, rc));
     81        dprintf(("!ERROR!: OSLibDosAliasMem: DosAliasMem %x %x returned %d", pb, cb, rc));
    8182        return rc;
    8283    }
     
    8485        rc = DosSetMem(pb, size, attr);
    8586        if(rc) {
    86             dprintf(("OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
     87            dprintf(("!ERROR!: OSLibDosAliasMem: DosSetMem (2) %x %x return %d", pb, size, rc));
    8788            return rc;
    8889        }
     
    9192}
    9293//******************************************************************************
     94//Allocate memory aligned at 64kb boundary
    9395//******************************************************************************
    9496DWORD OSLibDosAllocMem(LPVOID *lplpMemAddr, DWORD cbSize, DWORD flFlags)
     
    114116    rc = DosAllocMem(&pvMemAddr, cbSize, flFlags | flAllocMem);
    115117    if(rc) {
    116         dprintf(("DosAllocMem failed with rc %d", rc));
     118        dprintf(("!ERROR!: DosAllocMem failed with rc %d", rc));
    117119        return rc;
    118120    }
    119     //TODO!!!!!!!!!!!!
    120 #if 0
    121121    // already 64k aligned ?
    122     if((DWORD) pvMemAddr & 0xFFFF)
     122    if((ULONG) pvMemAddr & 0xFFFF)
    123123    {
    124         DWORD addr64kb;
     124        ULONG addr64kb;
     125
     126        //free misaligned allocated memory
     127        DosFreeMem(pvMemAddr);
    125128
    126129        //Allocate 64kb more so we can round the address to a 64kb aligned value
    127         rc = DosAllocMem((PPVOID)&addr64kb, cbSize + 64*1024,  PAG_READ | flAllocMem);
     130        rc = DosAllocMem((PPVOID)&addr64kb, cbSize + 64*1024,  (flFlags & ~PAG_COMMIT) | flAllocMem);
    128131        if(rc) {
    129             dprintf(("DosAllocMem failed with rc %d", rc));
     132            dprintf(("!ERROR!: DosAllocMem failed with rc %d", rc));
    130133            return rc;
    131134        }
     135        dprintf(("Allocate aligned memory %x -> %x", addr64kb, (addr64kb + 0xFFFF) & ~0xFFFF));
     136
    132137        if(addr64kb & 0xFFFF) {
    133             addr64kb = (addr64kb + 0xFFFF) & 0xFFFF;
     138            addr64kb         = (addr64kb + 0xFFFF) & ~0xFFFF;
    134139        }
    135140        pvMemAddr = (PVOID)addr64kb;
    136141
    137142        //and set the correct page flags for the request range
    138         rc = DosSetMem(pvMemAddr, cbSize, flFlags | flAllocMem);
    139     }
    140 #endif
     143        if((flFlags & ~PAG_COMMIT) != flFlags) {
     144            rc = DosSetMem(pvMemAddr, cbSize, flFlags);
     145            if(rc) {
     146                dprintf(("!ERROR!: DosSetMem failed with rc %d", rc));
     147                return rc;
     148            }
     149        }
     150    }
     151
    141152    if(!rc)
    142153        *lplpMemAddr = pvMemAddr;
     
    145156}
    146157//******************************************************************************
     158//Locate the base page of a memory allocation (the page with the PAG_BASE attribute)
     159//******************************************************************************
     160PVOID OSLibDosFindMemBase(LPVOID lpMemAddr)
     161{
     162    ULONG  ulAttr, ulSize, ulAddr;
     163    APIRET rc;
     164   
     165    rc = DosQueryMem(lpMemAddr, &ulSize, &ulAttr);
     166    if(rc != NO_ERROR) {
     167        dprintf(("!ERROR!: OSLibDosFindMemBase: DosQueryMem %x failed with rc %d", lpMemAddr, rc));
     168        return lpMemAddr;
     169    }
     170    if(!(ulAttr & PAG_BASE)) {
     171        //Not the base of the initial allocation (can happen due to alignment) or app
     172        //passing address inside memory allocation range
     173        ulAddr  = (DWORD)lpMemAddr & ~0xFFF;
     174        ulAddr -= PAGE_SIZE;
     175
     176        while(ulAddr > 0)
     177        {
     178            rc = DosQueryMem((PVOID)ulAddr, &ulSize, &ulAttr);
     179            if(rc) {
     180                dprintf(("!ERROR!: OSLibDosFindMemBase: DosQueryMem %x failed with rc %d", lpMemAddr, rc));
     181                DebugInt3();
     182                return NULL;
     183            }
     184            if(ulAttr & PAG_BASE) {
     185                //Memory below the 512 MB boundary is always aligned at 64kb and VirtualAlloc only
     186                //returns high memory (if OS/2 version supports it)
     187                //If it is above the 512 MB boundary, then we must make sure the right base address
     188                //is returned. VirtualAlloc allocates extra memory to make sure it can return addresses
     189                //aligned at 64kb. If extra pages are needed, then the allocation base is inside
     190                //the filler region. In that case we must return the next 64kb address as base.
     191                if(ulAddr > MEM_TILED_CEILING) {
     192                    ulAddr = (ulAddr + 0xFFFF) & ~0xFFFF;
     193                }
     194                lpMemAddr = (PVOID)ulAddr;
     195                break;
     196            }
     197            ulAddr -= PAGE_SIZE;
     198        }
     199    }
     200    return lpMemAddr;
     201}
     202//******************************************************************************
    147203//******************************************************************************
    148204DWORD OSLibDosFreeMem(LPVOID lpMemAddr)
    149205{
     206    ULONG  ulAttr, ulSize, ulAddr;
     207    APIRET rc;
     208
     209    ulAddr  = (DWORD)lpMemAddr & ~0xFFF;
     210
     211    //Find base within previous 64kb (alignment can add filler pages)
     212    for(int i=0;i<16;i++) {
     213        rc = DosQueryMem((PVOID)ulAddr, &ulSize, &ulAttr);
     214        if(rc != NO_ERROR) {
     215            dprintf(("!ERROR!: OSLibDosFreeMem: DosQueryMem %x failed with rc %d", lpMemAddr, rc));
     216            i = 16; //fail
     217            break;
     218        }
     219        if(ulAttr & PAG_BASE) {
     220            break;
     221        }
     222        ulAddr -= PAGE_SIZE;
     223    }
     224    if(i == 16) {
     225        //oh, oh. didn't find base; shouldn't happen!!
     226        dprintf(("!ERROR!: OSLibDosFreeMem: Unable to find base of %x", lpMemAddr));
     227        DebugInt3();
     228    }
     229    else {
     230        lpMemAddr = (PVOID)ulAddr;
     231    }
    150232    return DosFreeMem(lpMemAddr);
    151233}
Note: See TracChangeset for help on using the changeset viewer.