Esempio n. 1
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 );
}
Esempio n. 2
0
_WCRTLINK void _WCFAR *_fmalloc( size_t amt )
{
    unsigned        size;
    unsigned        offset;
    unsigned short  seg;
    unsigned short  prev_seg;
    struct heapblk _WCFAR *p;

    if( amt == 0  ||  amt > - (sizeof(struct heapblk) + TAG_SIZE*2) ) {
        return( (void _WCFAR *)NULL );
    }

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

    _AccessFHeap();
    for(;;) {
        if( size > __LargestSizeB4Rover ) {
            seg = __fheapRover;
        } else {
            __LargestSizeB4Rover = 0;   // force value to be updated
            seg = __fheap;
        }
        for(;;) {
            if( seg == 0 ) {
                seg = __AllocSeg( amt );
                if( seg == 0 )
                    break;
                if( __fheap == 0 ) {
                    __fheap = seg;
                } else {
                    p->nextseg = seg;
                    p = MK_FP( seg, 0 );
                    p->prevseg = prev_seg;
                }
            }
            for(;;) {
                __fheapRover = seg;
                offset = __MemAllocator( amt, seg, 0 );
                if( offset != 0 )
                    goto release_heap;
                if( __GrowSeg( seg, amt ) == 0 )
                    break;
            }
            prev_seg = seg;
            p = MK_FP( seg, 0 );
            if( p->largest_blk > __LargestSizeB4Rover ) {
                __LargestSizeB4Rover = p->largest_blk;
            }
            seg = p->nextseg;
        }
        if( __fmemneed( amt ) == 0 )
            break;
    }
    if( seg == 0 ) {
        offset = (unsigned)_nmalloc( amt );
        if( offset != 0 )
            seg = _DGroup();
    }
release_heap:
    _ReleaseFHeap();
    return( MK_FP( seg, offset ) );
}