From cc8b444e85e8efbd388cc35bd3fe83b5183ad18b Mon Sep 17 00:00:00 2001 From: Joshua Green Date: Sat, 1 Jun 2024 14:07:10 -0400 Subject: [PATCH] Hoping to simplify the logic by moving the boilerplate into functions. Also, implementing my TODO as a compile-time option. Primarily pushing now so that I can pull this into my testing infrastructure. --- DHT/fxf.c | 277 +++++++++++++++++++++++++++++++++--------------------- 1 file changed, 168 insertions(+), 109 deletions(-) diff --git a/DHT/fxf.c b/DHT/fxf.c index 5d07ba463..a9d9b465f 100644 --- a/DHT/fxf.c +++ b/DHT/fxf.c @@ -1,4 +1,4 @@ -#if defined (FXF) +#if defined(FXF) #include "debugging/assert.h" #include @@ -46,11 +46,20 @@ # endif #endif -#if !defined(MAX_ALIGNMENT) +#if defined(FXF_MAX_ALIGNMENT) +enum { + ENSURE_FXF_MAX_ALIGNMENT_IS_REASONABLE_POWER_OF_TWO = 1/((FXF_MAX_ALIGNMENT > 0) && + (FXF_MAX_ALIGNMENT <= (size_t)-1) && + !(FXF_MAX_ALIGNMENT & (FXF_MAX_ALIGNMENT - 1U))) +}; +# if ((FXF_MAX_ALIGNMENT <= 0) || (FXF_MAX_ALIGNMENT & (FXF_MAX_ALIGNMENT - 1U))) +# #error "ERROR: MAX_ALIGNMENT must be a power of 2." +# endif +#else # if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) -# define MAX_ALIGNMENT _Alignof(max_align_t) +# define FXF_MAX_ALIGNMENT _Alignof(max_align_t) # elif (defined(__cplusplus) && (__cplusplus >= 201103L)) -# define MAX_ALIGNMENT alignof(max_align_t) +# define FXF_MAX_ALIGNMENT alignof(max_align_t) # else # if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) # include @@ -70,9 +79,9 @@ long double floating_point; } max_aligned_union; }; -# define MAX_ALIGNMENT offsetof(struct GET_MAX_ALIGNMENT_TYPE, max_aligned_union) +# define FXF_MAX_ALIGNMENT offsetof(struct GET_MAX_ALIGNMENT_TYPE, max_aligned_union) # endif -#endif /*MAX_ALIGNMENT*/ +#endif /*FXF_MAX_ALIGNMENT*/ #if !defined(Nil) && !defined(New) && !defined(nNewUntyped) && !defined(nNewCallocUntyped) /* TODO: Is this the correct check for all of the below lines? */ # define Nil(type) ((type *)0) @@ -128,7 +137,7 @@ typedef struct { #if defined(DOS) /* MSDOS 16 Bit support (maxmemory <= 1 MB) */ #define SEGMENTED -#define ARENA_SEG_SIZE (CLIP_TO_MAX_POINTER_DIFFERENCE(32000) & ~(MAX_ALIGNMENT - 1U)) +#define ARENA_SEG_SIZE (CLIP_TO_MAX_POINTER_DIFFERENCE(32000) & ~(FXF_MAX_ALIGNMENT - 1U)) #define ARENA_SEG_COUNT ((1024*1024)/ARENA_SEG_SIZE) #define OSNAME "MSDOS" #define OSMAXMEM "1 MB" @@ -136,7 +145,7 @@ typedef struct { /* Win95/Win98/WinME can only allocate chunks up to 255 MB */ /* maxmemory <= 768 MB */ #define SEGMENTED -#define ARENA_SEG_SIZE (CLIP_TO_MAX_POINTER_DIFFERENCE(1000000) & ~(MAX_ALIGNMENT - 1U)) +#define ARENA_SEG_SIZE (CLIP_TO_MAX_POINTER_DIFFERENCE(1000000) & ~(FXF_MAX_ALIGNMENT - 1U)) #define ARENA_SEG_COUNT ((768*1024*1024)/ARENA_SEG_SIZE) #define OSNAME "Win95/Win98/WinME" #define OSMAXMEM "768 MB" @@ -160,7 +169,7 @@ enum #else ((((size_t)2048) /* This is needed only when sizeof(void*)==8. */ #endif - + (MAX_ALIGNMENT - 1U)) & ~(MAX_ALIGNMENT - 1U)) /* Round up if necessary. */ + + (FXF_MAX_ALIGNMENT - 1U)) & ~(FXF_MAX_ALIGNMENT - 1U)) /* Round up if necessary. */ }; enum { @@ -169,9 +178,9 @@ enum { }; #define BOTTOM_BIT_OF_FXFMINSIZE ((size_t)fxfMINSIZE & -(size_t)fxfMINSIZE) -#define MIN_ALIGNMENT_UNDERESTIMATE ((BOTTOM_BIT_OF_FXFMINSIZE > MAX_ALIGNMENT) ? MAX_ALIGNMENT : BOTTOM_BIT_OF_FXFMINSIZE) /* We'd prefer the top bit, but we'll compute that during fxfInit. - (Of course, they're probably the same.) - TODO: Can we compute what we want at compile time and just use it? */ +#define MIN_ALIGNMENT_UNDERESTIMATE ((BOTTOM_BIT_OF_FXFMINSIZE > FXF_MAX_ALIGNMENT) ? FXF_MAX_ALIGNMENT : BOTTOM_BIT_OF_FXFMINSIZE) /* We'd prefer the top bit, but we'll compute that during fxfInit. + (Of course, they're probably the same.) + TODO: Can we compute what we want at compile time and just use it? */ static size_t min_alignment= 0; /* for now */ static SizeHead SizeData[1 + ((fxfMAXSIZE - fxfMINSIZE)/MIN_ALIGNMENT_UNDERESTIMATE)]; /* Minimum allocation is (fxfMINSIZE + (MIN_ALIGNMENT_UNDERESTIMATE - 1U)) & ~(MIN_ALIGNMENT_UNDERESTIMATE - 1U). @@ -337,7 +346,7 @@ size_t fxfInit(size_t Size) { free(Arena); if (Size > MAX_POINTER_DIFFERENCE) Size= MAX_POINTER_DIFFERENCE; - Size&= ~(MAX_ALIGNMENT - 1U); + Size&= ~(FXF_MAX_ALIGNMENT - 1U); Arena= nNewUntyped(Size, char); if (!Arena) { ERROR_LOG3("%s: Sorry, cannot allocate arena of %" SIZE_T_PRINTF_SPECIFIER " <= %" SIZE_T_PRINTF_SPECIFIER " bytes\n", @@ -375,7 +384,7 @@ size_t fxfInit(size_t Size) { if (!min_alignment) { - min_alignment= MAX_ALIGNMENT; + min_alignment= FXF_MAX_ALIGNMENT; while (min_alignment > fxfMINSIZE) min_alignment>>= 1; } @@ -469,16 +478,54 @@ void fxfReset(void) * SPARC, HPPA, MIPS. We wouldn't need this when running on an * Intel *86 type of CPU, but also there, aligned access is faster. */ -#define PTRMASK (MAX_ALIGNMENT-1U) +#define PTRMASK (FXF_MAX_ALIGNMENT-1U) #define ALIGN_TO_MINIMUM(s) (((s) + (min_alignment - 1U)) & ~(min_alignment - 1U)) -#define TMDBG(x) if (0) x +#if defined(FXF_ENABLE_TMDBG) +# define TMDBG(x) do {x;} while (0) +#else /*FXF_ENABLE_TMDBG*/ +# define TMDBG(x) do {;} while (0) +#endif /*!FXF_ENABLE_TMDBG*/ + +static int pushOntoFreeStore(void * const ptr, size_t const size) { + SizeHead *cur_sh; + assert((size >= fxfMINSIZE) && + (size <= fxfMAXSIZE) && + !(size & (min_alignment - 1U))); + cur_sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(size)]; + if ((size >= sizeof cur_sh->FreeHead) || !cur_sh->FreeCount) { + if (size >= sizeof cur_sh->FreeHead) + memcpy(ptr, &cur_sh->FreeHead, sizeof cur_sh->FreeHead); + cur_sh->FreeHead= ptr; + cur_sh->FreeCount++; + TMDBG(printf(" FreeCount:%lu",cur_sh->FreeCount)); + return 1; + } + return 0; +} + +static void * popOffFreeStore(size_t const size) { + SizeHead *cur_sh; + void *ptr; + assert((size >= fxfMINSIZE) && + (size <= fxfMAXSIZE) && + !(size & (min_alignment - 1U))); + cur_sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(size)]; + ptr= cur_sh->FreeHead; + if (ptr) { + cur_sh->FreeCount--; + if (size < sizeof cur_sh->FreeHead) + cur_sh->FreeHead= Nil(void); + else + memcpy(&cur_sh->FreeHead, ptr, sizeof cur_sh->FreeHead); + } + return ptr; +} void *fxfAlloc(size_t size) { #if defined(LOG) || defined(DEBUG) static char const * const myname= "fxfAlloc"; #endif - SizeHead *sh; void *ptr= Nil(void); TMDBG(printf("fxfAlloc - size:%" SIZE_T_PRINTF_SPECIFIER,(size_t_printf_type)size)); @@ -501,21 +548,17 @@ void *fxfAlloc(size_t size) { // Round up to a multiple of min_alignment size= ALIGN_TO_MINIMUM(size); - sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(size)]; - if (sh->FreeHead) { -#if defined(SEGMENTED) - int ptrSegment; - ptrdiff_t ptrIndex; + ptr= popOffFreeStore(size); + + if (ptr) { + SizeHead *const sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(size)]; +#if defined(SEGMENTED) && defined(FXF_ENABLE_TMDBG) + ptrdiff_t ptrIndex; + int ptrSegment= CurrentSeg; #endif - ptr= sh->FreeHead; - if (size < sizeof sh->FreeHead) - sh->FreeHead= Nil(void); - else - memcpy(&sh->FreeHead, ptr, sizeof sh->FreeHead); - sh->FreeCount--; sh->MallocCount++; #if defined(SEGMENTED) - ptrSegment= CurrentSeg; +# if defined(FXF_ENABLE_TMDBG) if (CurrentSeg) { convert_pointer_to_int_type tmp= (convert_pointer_to_int_type)ptr; do { @@ -530,12 +573,13 @@ void *fxfAlloc(size_t size) { ptrIndex= pointerDifference(ptr, Arena[0]); FOUND_PUTATIVE_SEGMENT: TMDBG(printf(" FreeCount:%lu ptr-Arena[%d]:%" PTRDIFF_T_PRINTF_SPECIFIER " MallocCount:%lu\n",sh->FreeCount,ptrSegment,(ptrdiff_t_printf_type)ptrIndex,sh->MallocCount)); -#else +# endif /*FXF_ENABLE_TMDBG*/ +#else /*SEGMENTED*/ # if defined(FREEMAP) ClrRange(pointerDifference(ptr, Arena), size); # endif TMDBG(printf(" FreeCount:%lu ptr-Arena:%" PTRDIFF_T_PRINTF_SPECIFIER " MallocCount:%lu\n",sh->FreeCount,(ptrdiff_t_printf_type)pointerDifference(ptr, Arena),sh->MallocCount)); -#endif +#endif /*!SEGMENTED*/ } else { /* we have to allocate a new piece */ @@ -546,36 +590,28 @@ void *fxfAlloc(size_t size) { sizeCurrentSeg = (size_t)pointerDifference(TopFreePtr,BotFreePtr); TMDBG(printf(" sizeCurrentSeg:%" SIZE_T_PRINTF_SPECIFIER,(size_t_printf_type)sizeCurrentSeg)); if (sizeCurrentSeg>=size) { + SizeHead *sh; if (size&PTRMASK) { /* not fully aligned */ - size_t curBottomIndex; - size_t needed_alignment_mask= PTRMASK; - while (needed_alignment_mask >= size) - needed_alignment_mask>>= 1; + size_t curBottomIndex= #if defined(SEGMENTED) - curBottomIndex= (size_t)pointerDifference(BotFreePtr,Arena[CurrentSeg]); + (size_t)pointerDifference(BotFreePtr,Arena[CurrentSeg]); #else - curBottomIndex= (size_t)pointerDifference(BotFreePtr,Arena); + (size_t)pointerDifference(BotFreePtr,Arena); #endif + size_t needed_alignment_mask= PTRMASK; + while (needed_alignment_mask >= size) + needed_alignment_mask>>= 1; if (curBottomIndex & needed_alignment_mask) { - size_t const numBytesToAdd= (needed_alignment_mask - (curBottomIndex & needed_alignment_mask)) + 1U; - if (numBytesToAdd > (sizeCurrentSeg-size)) + if ((needed_alignment_mask - (curBottomIndex & needed_alignment_mask)) >= (sizeCurrentSeg-size)) goto NEXT_SEGMENT; do { size_t const cur_alignment= (curBottomIndex & -curBottomIndex); #if defined(FREEMAP) && !defined(SEGMENTED) SetRange(curBottomIndex,cur_alignment); #endif - if (cur_alignment >= fxfMINSIZE) { - SizeHead * const cur_sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(cur_alignment)]; - if ((cur_alignment >= sizeof cur_sh->FreeHead) || !cur_sh->FreeCount) { - if (cur_alignment >= sizeof cur_sh->FreeHead) - memcpy(BotFreePtr, &cur_sh->FreeHead, sizeof cur_sh->FreeHead); - cur_sh->FreeHead= BotFreePtr; - ++cur_sh->FreeCount; - TMDBG(printf(" FreeCount:%lu",cur_sh->FreeCount)); - } - } + if (cur_alignment >= fxfMINSIZE) + pushOntoFreeStore(BotFreePtr, cur_alignment); BotFreePtr= stepPointer(BotFreePtr, (ptrdiff_t)cur_alignment); curBottomIndex+= cur_alignment; } while (curBottomIndex & needed_alignment_mask); @@ -587,6 +623,7 @@ void *fxfAlloc(size_t size) { /* fully aligned */ ptr= (TopFreePtr= stepPointer(TopFreePtr, -(ptrdiff_t)size)); } + sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(size)]; sh->MallocCount++; #if defined(SEGMENTED) TMDBG(printf(" current seg ptr-Arena[%d]:%" PTRDIFF_T_PRINTF_SPECIFIER " MallocCount:%lu\n",CurrentSeg,(ptrdiff_t_printf_type)pointerDifference(ptr, Arena[CurrentSeg]),sh->MallocCount)); @@ -602,30 +639,14 @@ void *fxfAlloc(size_t size) { size_t curBottomIndex= (BotFreePtr - Arena[CurrentSeg]); while (curBottomIndex & PTRMASK) { size_t const cur_alignment= (curBottomIndex & -curBottomIndex); - if (cur_alignment >= fxfMINSIZE) { - SizeHead * const cur_sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(cur_alignment)]; - if ((cur_alignment >= sizeof cur_sh->FreeHead) || !cur_sh->FreeCount) { - if (cur_alignment >= sizeof cur_sh->FreeHead) - memcpy(BotFreePtr, &cur_sh->FreeHead, sizeof cur_sh->FreeHead); - cur_sh->FreeHead= BotFreePtr; - ++cur_sh->FreeCount; - TMDBG(printf(" FreeCount:%lu",cur_sh->FreeCount)); - } - } + if (cur_alignment >= fxfMINSIZE) + pushOntoFreeStore(BotFreePtr, cur_alignment); BotFreePtr= stepPointer(BotFreePtr, cur_alignment); curBottomIndex+= cur_alignment; } curBottomIndex= (size_t)(TopFreePtr-BotFreePtr); - if (curBottomIndex >= fxfMINSIZE) { - SizeHead * const cur_sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(curBottomIndex)]; - if ((curBottomIndex >= sizeof cur_sh->FreeHead) || !cur_sh->FreeCount) { - if (curBottomIndex >= sizeof cur_sh->FreeHead) - memcpy(BotFreePtr, &cur_sh->FreeHead, sizeof cur_sh->FreeHead); - cur_sh->FreeHead= BotFreePtr; - ++cur_sh->FreeCount; - TMDBG(printf(" FreeCount:%lu",cur_sh->FreeCount)); - } - } + if (curBottomIndex >= fxfMINSIZE) + pushOntoFreeStore(BotFreePtr, curBottomIndex); TMDBG(fputs(" next seg", stdout)); ++CurrentSeg; BotFreePtr= Arena[CurrentSeg]; @@ -633,15 +654,34 @@ void *fxfAlloc(size_t size) { goto START_LOOKING_FOR_CHUNK; } else +#endif /*SEGMENTED*/ + { ptr= Nil(void); -#else /*SEGMENTED*/ - ptr= Nil(void); -#endif /*!SEGMENTED*/ - /* TODO: Instead of returning Nil(void), should we try to satisfy the request by breaking - apart a larger block from the free store? - ADVANTAGE: may not have to return Nil(void) - DISADVANTAGE: we would no longer ever be able to use that contiguous memory to - satisfy a large request */ +#if defined(FXF_BREAK_APART_LARGER_CHUNK) + /* See if we can find a larger chunk to pull a piece out of. */ + for (size_t largerSize= size; largerSize < fxfMAXSIZE;) { + largerSize+= min_alignment; + ptr= popOffFreeStore(largerSize); + if (ptr) { + void *newPtr= stepPointer(ptr, size); + size_t cur_alignment= (size & -size); + SizeData[SIZEDATA_SIZE_TO_INDEX(size)].MallocCount++; + largerSize-= size; + while ((cur_alignment < FXF_MAX_ALIGNMENT) && (cur_alignment <= (largerSize>>1))) { + if (cur_alignment >= fxfMINSIZE) + pushOntoFreeStore(newPtr, cur_alignment); + newPtr= stepPointer(newPtr, cur_alignment); + largerSize-= cur_alignment; + size+= cur_alignment; + cur_alignment= (size & -size); + } + if (largerSize >= fxfMINSIZE) + pushOntoFreeStore(newPtr, largerSize); + break; + } + } +#endif /*FXF_BREAK_APART_LARGER_CHUNK*/ + } TMDBG(printf(" ptr:%p\n", ptr)); } } @@ -651,19 +691,19 @@ void *fxfAlloc(size_t size) { void fxfFree(void *ptr, size_t size) { -#if defined(LOG) || defined(DEBUG) - static char const * const myname= "fxfFree"; -#endif SizeHead *sh; +#if defined(FXF_ENABLE_TMDBG) || !defined(NDEBUG) ptrdiff_t ptrIndex; -#if defined(SEGMENTED) +#endif +#if defined(SEGMENTED) && defined(FXF_ENABLE_TMDBG) int ptrSegment; #endif if (!ptr) return; assert(!!size); #if defined(SEGMENTED) +# if defined(FXF_ENABLE_TMDBG) || !defined(NDEBUG) ptrSegment= CurrentSeg; if (CurrentSeg) { convert_pointer_to_int_type tmp= (convert_pointer_to_int_type)ptr; @@ -682,11 +722,14 @@ void fxfFree(void *ptr, size_t size) } FOUND_PUTATIVE_SEGMENT: TMDBG(printf("fxfFree - ptr-Arena[%d]:%" PTRDIFF_T_PRINTF_SPECIFIER " size:%" SIZE_T_PRINTF_SPECIFIER,ptrSegment,(ptrdiff_t_printf_type)ptrIndex,(size_t_printf_type)size)); -#else +# endif /*FXF_ENABLE_TMDBG*/ +#else /*SEGMENTED*/ +# if defined(FXF_ENABLE_TMDBG) || !defined(NDEBUG) ptrIndex= pointerDifference(ptr,Arena); +# endif assert((ptrIndex >= 0) && (ptrIndex < GlobalSize)); TMDBG(printf("fxfFree - ptr-Arena:%" PTRDIFF_T_PRINTF_SPECIFIER " size:%" SIZE_T_PRINTF_SPECIFIER,(ptrdiff_t_printf_type)ptrIndex,(size_t_printf_type)size)); -#endif +#endif /*!SEGMENTED*/ DBG((df, "%s(%p, %" SIZE_T_PRINTF_SPECIFIER ")\n", myname, (void *)ptr, (size_t_printf_type) size)); if (size < fxfMINSIZE) size= fxfMINSIZE; @@ -706,14 +749,13 @@ void fxfFree(void *ptr, size_t size) #endif if (ptrIndex > 0) { - size_t needed_alignment= MAX_ALIGNMENT; + size_t needed_alignment= FXF_MAX_ALIGNMENT; while (needed_alignment > size) needed_alignment>>= 1; assert(!(((size_t)ptrIndex) & (needed_alignment - 1U))); } } #endif - sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(size)]; if (size&PTRMASK) { /* not fully aligned size */ TMDBG(printf(" BotFreePtr-ptr:%" PTRDIFF_T_PRINTF_SPECIFIER,(ptrdiff_t_printf_type)pointerDifference(BotFreePtr,ptr))); @@ -725,13 +767,7 @@ void fxfFree(void *ptr, size_t size) #if defined(FREEMAP) && !defined(SEGMENTED) SetRange((pointerDifference(ptr,Arena),size); #endif - if ((size >= sizeof sh->FreeHead) || !sh->FreeHead) { - if (size >= sizeof sh->FreeHead) - memcpy(ptr, &sh->FreeHead, sizeof sh->FreeHead); - sh->FreeHead= ptr; - ++sh->FreeCount; - TMDBG(printf(" FreeCount:%lu",sh->FreeCount)); - } + pushOntoFreeStore(ptr, size); } } else { @@ -745,27 +781,24 @@ void fxfFree(void *ptr, size_t size) #if defined(FREEMAP) && !defined(SEGMENTED) SetRange(pointerDifference(ptr,Arena),size); #endif - if ((size >= sizeof sh->FreeHead) || !sh->FreeCount) { - if (size >= sizeof sh->FreeHead) - memcpy(ptr, &sh->FreeHead, sizeof sh->FreeHead); - sh->FreeHead= ptr; - ++sh->FreeCount; - TMDBG(printf(" FreeCount:%lu",sh->FreeCount)); - } + pushOntoFreeStore(ptr, size); } } - --sh->MallocCount; + sh= &SizeData[SIZEDATA_SIZE_TO_INDEX(size)]; + sh->MallocCount--; TMDBG(printf(" MallocCount:%lu",sh->MallocCount)); TMDBG(putchar('\n')); } void *fxfReAlloc(void *ptr, size_t OldSize, size_t NewSize) { void *nptr; + size_t original_allocation; if (!ptr) { assert(!OldSize); return fxfAlloc(NewSize); } + assert(OldSize && (OldSize <= fxfMAXSIZE)); #if !defined(NDEBUG) # if defined(SEGMENTED) if (!CurrentSeg) /* Otherwise we'd be relying on converting to convert_pointer_to_int_type, @@ -792,7 +825,7 @@ void *fxfReAlloc(void *ptr, size_t OldSize, size_t NewSize) { # else assert(allocatedSize <= (GlobalSize - ptrIndex)); # endif - needed_alignment= MAX_ALIGNMENT; + needed_alignment= FXF_MAX_ALIGNMENT; while (needed_alignment > allocatedSize) needed_alignment>>= 1; assert(!(((size_t)ptrIndex) & (needed_alignment - 1U))); @@ -804,14 +837,40 @@ void *fxfReAlloc(void *ptr, size_t OldSize, size_t NewSize) { fxfFree(ptr, OldSize); return Nil(void); } - /* TODO: It may be worth trying to return ptr if ALIGN_TO_MINIMUM(OldSize) >= NewSize. - To go along with this, we'd have to carefully add any excess to the free store. - In the !defined(SEGMENTED) case this is likely easy, but in the defined(SEGMENTED) - case it may be difficult. Regardless, the computations to set this up -- or even - determine if it's possible -- are kind of annoying, and they'd only be worthwhile - if we hit this possibility frequently (and if the alternative below is expensive - or proves impossible). This all would need to be investigated. - */ + original_allocation= OldSize; + if (original_allocation < fxfMINSIZE) + original_allocation= fxfMINSIZE; + original_allocation= ALIGN_TO_MINIMUM(original_allocation); + if (NewSize <= original_allocation) + { + size_t needed_allocation= NewSize; + if (needed_allocation < fxfMINSIZE) + needed_allocation= fxfMINSIZE; + needed_allocation= ALIGN_TO_MINIMUM(needed_allocation); + if (needed_allocation == original_allocation) + return ptr; +#if defined(FXF_BREAK_APART_LARGER_CHUNK) + if (needed_allocation < original_allocation) + { + size_t cur_alignment= (needed_allocation & -needed_allocation); + nptr= stepPointer(ptr, needed_allocation); + SizeData[SIZEDATA_SIZE_TO_INDEX(original_allocation)].MallocCount--; + SizeData[SIZEDATA_SIZE_TO_INDEX(needed_allocation)].MallocCount++; + original_allocation-= needed_allocation; + while ((cur_alignment < FXF_MAX_ALIGNMENT) && (cur_alignment <= (original_allocation>>1))) { + if (cur_alignment >= fxfMINSIZE) + pushOntoFreeStore(nptr, cur_alignment); + nptr= stepPointer(nptr, cur_alignment); + original_allocation-= cur_alignment; + needed_allocation+= cur_alignment; + cur_alignment= (needed_allocation & -needed_allocation); + } + if (original_allocation >= fxfMINSIZE) + pushOntoFreeStore(nptr, original_allocation); + return ptr; + } +#endif /*FXF_BREAK_APART_LARGER_CHUNK*/ + } nptr= fxfAlloc(NewSize); if (nptr) {