_WCRTLINK int _fheapchk( void ) { struct _heapinfo hi; int heap_status; unsigned long free_size; _AccessFHeap(); heap_status = checkFreeList( &free_size ); if( heap_status != _HEAPOK ) { _ReleaseFHeap(); return( heap_status ); } hi._pentry = NULL; while( (heap_status = __HeapWalk( &hi, __fheapbeg, _NULLSEG )) == _HEAPOK ) { if( hi._useflag == _FREEENTRY ) { heap_status = checkFree( hi._pentry ); if( heap_status != _HEAPOK ) break; free_size -= hi._size; } } if( free_size != 0 ) { heap_status = _HEAPBADNODE; } else if( heap_status == _HEAPBADPTR ) { heap_status = _HEAPBADNODE; } else if( heap_status == _HEAPEND ) { heap_status = _HEAPOK; } _ReleaseFHeap(); return( heap_status ); }
_WCRTLINK int _bfreeseg( __segment seg ) { __segment heap_seg; __segment prev_seg; struct heapblk _WCFAR *heap; struct heapblk _WCFAR *next_heap; struct heapblk _WCFAR *prev_heap; _AccessFHeap(); heap = MK_FP( seg, 0 ); heap_seg = seg; seg = heap->nextseg; /* unlink from heap list */ prev_seg = heap->prevseg; if( seg != 0 ) { next_heap = MK_FP( seg, 0 ); next_heap->prevseg = prev_seg; } if( prev_seg == 0 ) { __bheap = seg; } else { prev_heap = MK_FP( prev_seg, 0 ); prev_heap->nextseg = seg; } _ReleaseFHeap(); return( __FreeSeg( heap_seg ) ); }
_WCRTLINK int _fheapwalk( struct _heapinfo *entry ) { int heap_status; _AccessFHeap(); heap_status = __HeapWalk( entry, __fheap, 0 ); _ReleaseFHeap(); return( heap_status ); }
_WCRTLINK int _bheapwalk( __segment seg, struct _heapinfo *entry ) { int heap_status; if( seg == _DGroup() ) return( _nheapwalk( entry ) ); _AccessFHeap(); heap_status = __HeapWalk( entry, seg == _NULLSEG ? __bheap : seg, seg ); _ReleaseFHeap(); return( heap_status ); }
_WCRTLINK int _bfreeseg( __segment seg ) { __segment next_seg; __segment prev_seg; _AccessFHeap(); /* unlink from heap list */ prev_seg = HEAP( seg )->prevseg; next_seg = HEAP( seg )->nextseg; if( next_seg != _NULLSEG ) { HEAP( next_seg )->prevseg = prev_seg; } if( prev_seg == _NULLSEG ) { __bheapbeg = next_seg; } else { HEAP( prev_seg )->nextseg = next_seg; } _ReleaseFHeap(); return( __FreeSeg( seg ) ); }
_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 ) ); }