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/os2heap.cpp

    r7728 r8877  
    1 /* $Id: os2heap.cpp,v 1.32 2002-01-06 16:48:47 sandervl Exp $ */
     1/* $Id: os2heap.cpp,v 1.33 2002-07-15 14:28:51 sandervl Exp $ */
    22
    33/*
     
    77 *
    88 *
     9 * NOTE: Do NOT use high memory here. Risky with 16 bits tcpip stack
     10 *       If this is ever changed, then you must use VirtualAlloc!
     11 *
    912 * NOTE: ReAlloc allocates memory using Alloc if memory pointer == NULL
    1013 *       WINE controls depend on this, even though it apparently
     
    6467OS2Heap::OS2Heap(DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize)
    6568{
    66   OS2Heap *curheap = OS2Heap::heap;
     69    OS2Heap *curheap = OS2Heap::heap;
    6770 
    6871#ifdef DEBUG
    69   totalAlloc   = 0;
    70 #endif
    71   fInitialized = 0;
    72   nrHeaps      = 0;
    73   heapelem     = NULL;
    74 
    75   dwInitialSize       = (dwInitialSize >= 0x4000) ? dwInitialSize : 0x4000;
    76 
    77   this->dwMaximumSize = dwMaximumSize;
    78   this->dwInitialSize = dwInitialSize;
    79   this->flOptions     = flOptions;
    80 
    81   heaplistmutex.enter();
    82   if(curheap != NULL) {
     72    totalAlloc   = 0;
     73#endif
     74    fInitialized = 0;
     75    nrHeaps      = 0;
     76    heapelem     = NULL;
     77
     78    /* round the size up to a multiple of 64K */
     79    //NOTE: MUST use 64kb here or else we are at risk of running out of virtual
     80    //      memory space. (when allocating 4kb we actually get 4kb + 60k uncommited)
     81    dwInitialSize       = ( (dwInitialSize / 65536) + 1) * 65536;
     82
     83    this->dwMaximumSize = dwMaximumSize;
     84    this->dwInitialSize = dwInitialSize;
     85    this->flOptions     = flOptions;
     86
     87    heaplistmutex.enter();
     88    if(curheap != NULL) {
    8389        while(curheap->next != NULL) {
    8490                curheap = curheap->next;
    8591        }
    8692        curheap->next = this;
    87   }
    88   else  heap = this;
    89   next = NULL;
    90 
    91   heaplistmutex.leave();
    92 
    93   APIRET rc;
    94 
    95   rc = DosAllocMem((PPVOID)&pInitialHeapMem, dwInitialSize, PAG_READ|PAG_WRITE|PAG_COMMIT);
    96   if(rc != 0) {
    97         dprintf(("OS2Heap::OS2Heap: DosAllocSharedMem failed with %d", rc));
     93    }
     94    else  heap = this;
     95    next = NULL;
     96
     97    heaplistmutex.leave();
     98
     99    APIRET rc;
     100
     101    rc = DosAllocMem((PPVOID)&pInitialHeapMem, dwInitialSize, PAG_READ|PAG_WRITE|PAG_COMMIT);
     102    if(rc != 0) {
     103            dprintf(("OS2Heap::OS2Heap: DosAllocSharedMem failed with %d", rc));
    98104        DebugInt3();
    99   }
    100   uheap = _ucreate(pInitialHeapMem, dwInitialSize, _BLOCK_CLEAN,
    101                    _HEAP_REGULAR, getmoreHeapMem, releaseHeapMem);
    102   if(uheap == NULL) {
    103         DosFreeMem(pInitialHeapMem);
     105    }
     106    uheap = _ucreate(pInitialHeapMem, dwInitialSize, _BLOCK_CLEAN,
     107                     _HEAP_REGULAR, getmoreHeapMem, releaseHeapMem);
     108    if(uheap == NULL) {
     109            DosFreeMem(pInitialHeapMem);
    104110        pInitialHeapMem = NULL;
    105         dprintf(("OS2Heap::OS2Heap: _ucreate failed!"));
     111            dprintf(("OS2Heap::OS2Heap: _ucreate failed!"));
    106112        DebugInt3();
    107   }
    108   hPrimaryHeap = (HANDLE)uheap;
    109   dprintf(("KERNEL32:  HeapCreate: initial size %d, max size %d (flags %X) returned %X\n", dwInitialSize, dwMaximumSize, flOptions, hPrimaryHeap));
     113    }
     114    hPrimaryHeap = (HANDLE)uheap;
     115    dprintf(("KERNEL32:  HeapCreate: initial size %d, max size %d (flags %X) returned %X\n", dwInitialSize, dwMaximumSize, flOptions, hPrimaryHeap));
    110116}
    111117//******************************************************************************
     
    113119OS2Heap::~OS2Heap()
    114120{
    115  OS2Heap *curheap = OS2Heap::heap;
    116  int i;
    117  
    118   // invalidate handle cache
    119   fhhm_lastHandle = 0;
    120   fhhm_lastHeap   = NULL;
    121  
    122  
    123   dprintf(("dtr OS2Heap, hPrimaryHeap = %X\n", hPrimaryHeap));
    124 
    125   heaplistmutex.enter();
    126   if(heap == this) {
     121    OS2Heap *curheap = OS2Heap::heap;
     122    int i;
     123 
     124    // invalidate handle cache
     125    fhhm_lastHandle = 0;
     126    fhhm_lastHeap   = NULL;
     127 
     128    dprintf(("dtr OS2Heap, hPrimaryHeap = %X\n", hPrimaryHeap));
     129
     130    heaplistmutex.enter();
     131    if(heap == this) {
    127132        heap = next;
    128   }
    129   else {
     133    }
     134    else {
    130135        while(curheap->next != NULL) {
    131136                if(curheap->next == this) {
     
    135140                curheap = curheap->next;
    136141        }
    137   }
    138   heaplistmutex.leave();
    139 
    140   if(uheap) {
    141         _uclose(uheap);
    142         _udestroy(uheap, _FORCE);
    143         uheap = NULL;
    144   }
    145   if(pInitialHeapMem) {
    146         DosFreeMem(pInitialHeapMem);
    147         pInitialHeapMem = NULL;
    148   }
    149 
    150   dprintf(("dtr OS2Heap, hPrimaryHeap = %X done\n", hPrimaryHeap));
     142    }
     143    heaplistmutex.leave();
     144
     145    if(uheap) {
     146        _uclose(uheap);
     147        _udestroy(uheap, _FORCE);
     148        uheap = NULL;
     149    }     
     150    if(pInitialHeapMem) {
     151        DosFreeMem(pInitialHeapMem);
     152        pInitialHeapMem = NULL;
     153    }
     154
     155    dprintf(("dtr OS2Heap, hPrimaryHeap = %X done\n", hPrimaryHeap));
    151156}
    152157//******************************************************************************
     
    154159LPVOID OS2Heap::Alloc(DWORD dwFlags, DWORD dwBytes)
    155160{
    156  HEAPELEM *lpHeapObj;
    157  LPVOID    lpMem;
    158  DWORD     dwAllocBytes;
     161    HEAPELEM *lpHeapObj;
     162    LPVOID    lpMem;
     163    DWORD     dwAllocBytes;
    159164
    160165//  dprintf(("OS2Heap::Alloc\n"));
    161166
    162   //size must be multiple of 8 bytes
    163   dwAllocBytes = HEAP_ALIGN(dwBytes);
    164 
    165   lpMem = _umalloc(uheap, dwAllocBytes + HEAP_OVERHEAD);
    166   if(lpMem == NULL) {
    167       dprintf(("OS2Heap::Alloc, lpMem == NULL"));
    168       return(NULL);
    169   }
    170   if(dwFlags & HEAP_ZERO_MEMORY) {
    171       memset(lpMem, 0, dwAllocBytes+HEAP_OVERHEAD);
    172   }
     167    //size must be multiple of 8 bytes
     168    dwAllocBytes = HEAP_ALIGN(dwBytes);
     169
     170    lpMem = _umalloc(uheap, dwAllocBytes + HEAP_OVERHEAD);
     171    if(lpMem == NULL) {
     172        dprintf(("OS2Heap::Alloc, lpMem == NULL"));
     173        return(NULL);
     174    }
     175    if(dwFlags & HEAP_ZERO_MEMORY) {
     176        memset(lpMem, 0, dwAllocBytes+HEAP_OVERHEAD);
     177    }
    173178 
    174179#ifdef DEBUG
    175   totalAlloc += dwAllocBytes;
    176 #endif
    177  
    178   //align at 8 byte boundary
    179   lpHeapObj          = (HEAPELEM *)HEAP_ALIGN(lpMem);
    180   lpHeapObj->lpMem   = lpMem;
    181   lpHeapObj->magic   = MAGIC_NR_HEAP;
    182   lpHeapObj->orgsize = dwBytes; //original size
    183   lpHeapObj->cursize = dwBytes; //original size
     180    totalAlloc += dwAllocBytes;
     181#endif
     182 
     183    //align at 8 byte boundary
     184    lpHeapObj          = (HEAPELEM *)HEAP_ALIGN(lpMem);
     185    lpHeapObj->lpMem   = lpMem;
     186    lpHeapObj->magic   = MAGIC_NR_HEAP;
     187    lpHeapObj->orgsize = dwBytes;       //original size
     188    lpHeapObj->cursize = dwBytes;       //original size
    184189 
    185   return(LPVOID)(lpHeapObj+1);
     190    return(LPVOID)(lpHeapObj+1);
    186191}
    187192//******************************************************************************
     
    189194DWORD OS2Heap::Size(DWORD dwFlags, PVOID lpMem)
    190195{
    191  HEAPELEM *helem = GET_HEAPOBJ(lpMem);
    192 
    193   if(lpMem == NULL) {
     196    HEAPELEM *helem = GET_HEAPOBJ(lpMem);
     197
     198    if(lpMem == NULL) {
    194199        dprintf(("OS2Heap::Size lpMem == NULL\n"));
    195200        return -1;
    196   }
    197   /* verify lpMem address */
    198   if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
    199   {
     201    }
     202    /* verify lpMem address */
     203    if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
     204    {
     205        dprintf(("OS2Heap::Size ERROR BAD HEAP POINTER:%X\n", lpMem));
     206        return -1;
     207    }
     208
     209    if(helem->magic != MAGIC_NR_HEAP)
     210    {
    200211        dprintf(("OS2Heap::Size ERROR BAD HEAP POINTER:%X\n", lpMem));
    201212        return -1;
    202   }
    203 
    204   if(helem->magic != MAGIC_NR_HEAP)
    205   {
    206         dprintf(("OS2Heap::Size ERROR BAD HEAP POINTER:%X\n", lpMem));
    207         return -1;
    208   }
    209   return helem->cursize;  //return current size of memory block
     213    }
     214    return helem->cursize;  //return current size of memory block
    210215}
    211216//******************************************************************************
     
    213218LPVOID OS2Heap::ReAlloc(DWORD dwFlags, LPVOID lpMem, DWORD dwBytes)
    214219{
    215   HEAPELEM *helem = GET_HEAPOBJ(lpMem);
    216   LPVOID lpNewMem;
    217   int    i, maxSize;
    218 
    219   if (dwBytes == 0) return NULL;         // intercept stupid parameters
    220 
    221   //NOTE: Allocate memory using Alloc -> WINE controls depend on this, even
    222   //      though it apparently doesn't work in Windows.
    223   if (lpMem == 0)   return Alloc(dwFlags, dwBytes);
     220    HEAPELEM *helem = GET_HEAPOBJ(lpMem);
     221    LPVOID lpNewMem;
     222    int    i, maxSize;
     223
     224    if (dwBytes == 0) return NULL;         // intercept stupid parameters
     225
     226    //NOTE: Allocate memory using Alloc -> WINE controls depend on this, even
     227    //      though it apparently doesn't work in Windows.
     228    if (lpMem == 0)   return Alloc(dwFlags, dwBytes);
    224229//  if (lpMem == 0)   return NULL;
    225230
    226   if (helem->magic != MAGIC_NR_HEAP)
    227   {
    228     dprintf(("OS2Heap::ReAlloc ERROR BAD HEAP POINTER:%X\n", lpMem));
    229     return lpMem;
    230   }
    231 
    232   maxSize = HEAP_ALIGN(helem->orgsize);
    233   if (dwBytes <= maxSize) {
    234        dprintf(("ReAlloc with smaller size than original (%d); return old pointer", maxSize));
    235        //update current size so HeapSize will return the right value
    236        helem->cursize = dwBytes; 
    237        return lpMem; // if reallocation with same size don't do anything
    238   }
    239   lpNewMem = Alloc(dwFlags, dwBytes);
    240   memcpy(lpNewMem, lpMem, dwBytes < maxSize ? dwBytes : maxSize);
    241   Free(0, lpMem);
    242 
    243   if(lpNewMem == NULL)
    244   {
    245      dprintf(("OS2Heap::ReAlloc, no more memory left\n"));
    246   }
    247 
    248   return(lpNewMem);
     231    if (helem->magic != MAGIC_NR_HEAP)
     232    {
     233        dprintf(("OS2Heap::ReAlloc ERROR BAD HEAP POINTER:%X\n", lpMem));
     234        return lpMem;
     235    }
     236
     237    maxSize = HEAP_ALIGN(helem->orgsize);
     238    if (dwBytes <= maxSize) {
     239        dprintf(("ReAlloc with smaller size than original (%d); return old pointer", maxSize));
     240        //update current size so HeapSize will return the right value
     241        helem->cursize = dwBytes; 
     242        return lpMem; // if reallocation with same size don't do anything
     243    }
     244    lpNewMem = Alloc(dwFlags, dwBytes);
     245    memcpy(lpNewMem, lpMem, dwBytes < maxSize ? dwBytes : maxSize);
     246    Free(0, lpMem);
     247
     248    if(lpNewMem == NULL)
     249    {
     250        dprintf(("OS2Heap::ReAlloc, no more memory left\n"));
     251    }
     252   
     253    return(lpNewMem);
    249254}
    250255//******************************************************************************
     
    252257BOOL OS2Heap::Free(DWORD dwFlags, LPVOID lpMem)
    253258{
    254   HEAPELEM *helem = GET_HEAPOBJ(lpMem);
    255 
    256   /* verify lpMem address */
    257   if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
    258   {
     259    HEAPELEM *helem = GET_HEAPOBJ(lpMem);
     260
     261    /* verify lpMem address */
     262    if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
     263    {
    259264        dprintf(("OS2Heap::Free ERROR BAD HEAP POINTER:%X\n", lpMem));
    260265        return FALSE;
    261   }
    262 
    263   if(helem->magic != MAGIC_NR_HEAP)
    264   {
     266    }
     267
     268    if(helem->magic != MAGIC_NR_HEAP)
     269    {
    265270        dprintf(("OS2Heap::Free ERROR BAD HEAP POINTER:%X\n", lpMem));
    266271        return FALSE;
    267   }
     272    }
    268273
    269274#ifdef DEBUG1
    270   int size = Size(0, lpMem);
    271   dprintf(("OS2Heap::Free lpMem = %X, size %d\n", lpMem, size));
     275    int size = Size(0, lpMem);
     276    dprintf(("OS2Heap::Free lpMem = %X, size %d\n", lpMem, size));
    272277#ifdef DEBUG
    273   totalAlloc -= size;
    274 #endif
    275 #endif
    276 
    277   free(helem->lpMem);
    278   return(TRUE);
     278    totalAlloc -= size;
     279#endif
     280#endif
     281
     282    free(helem->lpMem);
     283    return(TRUE);
    279284}
    280285//******************************************************************************
     
    282287DWORD OS2Heap::Compact(DWORD dwFlags)
    283288{
    284   dprintf(("OS2Heap::Compact, %X- stub\n", dwFlags));
    285   return(0);
     289    dprintf(("OS2Heap::Compact, %X- stub\n", dwFlags));
     290    return(0);
    286291}
    287292//******************************************************************************
     
    289294BOOL OS2Heap::Validate(DWORD dwFlags, LPCVOID lpMem)
    290295{
    291   HEAPELEM *helem = GET_HEAPOBJ(lpMem);
    292 
    293   dprintf(("OS2Heap::Validate, %X %X", dwFlags, lpMem));
    294 
    295   /* verify lpMem address */
    296   if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
    297   {
     296    HEAPELEM *helem = GET_HEAPOBJ(lpMem);
     297
     298    dprintf(("OS2Heap::Validate, %X %X", dwFlags, lpMem));
     299
     300    /* verify lpMem address */
     301    if (lpMem >= (LPVOID)ulMaxAddr || lpMem < (LPVOID)0x10000)
     302    {
    298303        dprintf(("OS2Heap::Validate BAD HEAP POINTER:%X\n", lpMem));
    299304        return FALSE;
    300   }
    301 
    302   if(helem->magic != MAGIC_NR_HEAP)
    303   {
     305    }
     306
     307    if(helem->magic != MAGIC_NR_HEAP)
     308    {
    304309        dprintf(("OS2Heap::Validate BAD HEAP POINTER:%X\n", lpMem));
    305310        return FALSE;
    306   }
    307   return(TRUE);
     311    }
     312    return(TRUE);
    308313}
    309314//******************************************************************************
     
    311316BOOL OS2Heap::Walk(void *lpEntry)
    312317{
    313   dprintf(("OS2Heap::Walk, %X - stub? (TRUE)\n", lpEntry));
    314   return(TRUE);
     318    dprintf(("OS2Heap::Walk, %X - stub? (TRUE)\n", lpEntry));
     319    return(TRUE);
    315320}
    316321//******************************************************************************
     
    363368void * _LNK_CONV getmoreHeapMem(Heap_t pHeap, size_t *size, int *clean)
    364369{
    365  APIRET rc;
    366  PVOID newblock;
    367 
    368   dprintf(("KERNEL32: getmoreHeapMem(%08xh, %08xh, %08xh)", pHeap, *size, *clean));
    369 
    370   /* round the size up to a multiple of 64K */
    371   //NOTE: MUST use 64kb here or else we are at risk of running out of virtual
    372   //      memory space. (when allocating 4kb we actually get 4kb + 60k uncommited)
    373   *size = ( (*size / 65536) + 1) * 65536;
    374 
    375   rc = DosAllocMem(&newblock, *size, PAG_READ|PAG_WRITE|PAG_COMMIT|PAG_EXECUTE);
    376 ////  rc = DosAllocMem(&newblock, *size, flAllocMem|PAG_READ|PAG_WRITE|PAG_COMMIT|PAG_EXECUTE);
    377   if(rc != 0) {
    378         dprintf(("getmoreHeapMem: DosAllocMem failed with %d", rc));
    379         return FALSE;
    380   }
    381   *clean = _BLOCK_CLEAN;
    382   dprintf(("KERNEL32: getmoreHeapMem %x %d", newblock, *size));
    383   return newblock;
     370    APIRET rc;
     371    PVOID newblock;
     372
     373    dprintf(("KERNEL32: getmoreHeapMem(%08xh, %08xh, %08xh)", pHeap, *size, *clean));
     374
     375    /* round the size up to a multiple of 64K */
     376    //NOTE: MUST use 64kb here or else we are at risk of running out of virtual
     377    //      memory space. (when allocating 4kb we actually get 4kb + 60k uncommited)
     378    *size = ( (*size / 65536) + 1) * 65536;
     379
     380    rc = DosAllocMem(&newblock, *size, PAG_READ|PAG_WRITE|PAG_COMMIT|PAG_EXECUTE);
     381    if(rc != 0) {
     382        dprintf(("getmoreHeapMem: DosAllocMem failed with %d", rc));
     383        return FALSE;
     384    }
     385    *clean = _BLOCK_CLEAN;
     386    dprintf(("KERNEL32: getmoreHeapMem %x %d", newblock, *size));
     387    return newblock;
    384388}
    385389//******************************************************************************
     
    387391void _LNK_CONV releaseHeapMem(Heap_t pHeap, void *block, size_t size)
    388392{
    389   dprintf(("KERNEL32: releaseHeapMem %x %x %d", pHeap, block, size));
    390   DosFreeMem(block);
    391 }
    392 //******************************************************************************
    393 //******************************************************************************
     393    dprintf(("KERNEL32: releaseHeapMem %x %x %d", pHeap, block, size));
     394    DosFreeMem(block);
     395}
     396//******************************************************************************
     397//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.