_WCRTLINK __segment _bheapseg( size_t size ) { __segment seg; heapblk __based( seg ) *p; seg = __AllocSeg( size ); if( seg == _NULLSEG ) return( _NULLSEG ); p = 0; p->nextseg = __bheap; __bheap = seg; seg = p->nextseg; if( seg != _NULLSEG ) { p->prevseg = __bheap; } return( __bheap ); }
_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 ) ); }