_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 ); }
_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 ) ); }