Beispiel #1
0
_WCRTLINK void _WCNEAR *_nexpand( void _WCNEAR *stg, size_t req_size )
    {
        struct {
            unsigned expanded : 1;
        } flags;
        int retval;
        size_t growth_size;

        flags.expanded = 0;
        _AccessNHeap();
        for( ;; ) {
            retval = __HeapManager_expand( _DGroup(),
                                           (unsigned) stg,
                                           req_size,
                                           &growth_size );
            if( retval == __HM_SUCCESS ) {
                _ReleaseNHeap();
                return( stg );
            }
            if( retval == __HM_FAIL || !__IsCtsNHeap() ) break;
            if( retval == __HM_TRYGROW ) {
                if( flags.expanded ) break;
                if( __ExpandDGROUP( growth_size ) == 0 ) {
                    break;
                }
                flags.expanded = 1;
            }
        }
        _ReleaseNHeap();
        return( NULL );
    }
Beispiel #2
0
_WCRTLINK void _WCNEAR *_nmalloc( size_t amt )
{
    unsigned        largest;
    unsigned        size;
    unsigned        ptr;
    unsigned char   expanded;
    mheapptr        miniheap_ptr;

#   if defined(__WARP__)
    int             use_obj_any;
#   endif // __WARP__

    if( (amt == 0) || (amt > -sizeof(struct heapblk)) ) {
        return( (void _WCNEAR *)NULL );
    }

    // Try to determine which miniheap to begin allocating from.
    // first, round up the amount
    size = (amt + TAG_SIZE + ROUND_SIZE) & ~ROUND_SIZE;
    if( size < FRL_SIZE ) {
        size = FRL_SIZE;
    }

    _AccessNHeap();
    ptr = 0;
    expanded = 0;
    for(;;) {
#       if defined(__WARP__)
        // Need to update each pass in case 1st DosAllocMem determines OBJ_ANY not supported
        use_obj_any = _os2_obj_any_supported && _os2_use_obj_any;
#       endif
        // Figure out where to start looking for free blocks
        if( size > __LargestSizeB4MiniHeapRover ) {
            miniheap_ptr = __MiniHeapRover;
            if( miniheap_ptr == NULL ) {
                __LargestSizeB4MiniHeapRover = 0;   // force to be updated
                miniheap_ptr = __nheapbeg;
            }
        } else {
            __LargestSizeB4MiniHeapRover = 0;   // force to be updated
            miniheap_ptr = __nheapbeg;
        }
        // Search for free block
        for(;;) {
            if( miniheap_ptr == NULL ) {
                break;                  // Expand heap and retry maybe
            }
            __MiniHeapRover = miniheap_ptr;
            largest = miniheap_ptr->largest_blk;
#   if defined(__WARP__)
            if( use_obj_any == ( miniheap_ptr->used_obj_any != 0 ) ) {
#   endif // __WARP__
              if( largest >= amt ) {
                  ptr = __MemAllocator( amt, _DGroup(), (unsigned)miniheap_ptr );
                  if( ptr != 0 ) {
                      goto lbl_release_heap;
                  }
              }
#   if defined(__WARP__)
            }
#   endif // __WARP__
            if( largest > __LargestSizeB4MiniHeapRover ) {
                __LargestSizeB4MiniHeapRover = largest;
            }
            miniheap_ptr = miniheap_ptr->next;
        } /* forever */
        // OS/2 only - if not block of requested type, will allocate one and find in 2nd pass
        // Try to expand heap and retry
        if( expanded || !__ExpandDGROUP( amt ) ) {
            if( !__nmemneed( amt ) ) {
                break;                  // give up
            }
            expanded = 0;
        } else {
            expanded = 1;
        }
    } /* forever */
lbl_release_heap:
    _ReleaseNHeap();
    return( (void _WCNEAR *)ptr );
}