FRAMEWORK/MemChain.hpp
//---------------------------------------------------------------------------
// Exclude Range from Empty list (Allocate chunk of memory)
// First page is BlockHdr and cannot fit MaxPageFree
// Min allocated size is 'sizeof(SEmpty)' (8 bytes)
// 6 times faster than HeapAlloc on Windows :)
// Most allocators put a great effort in preserving size of an allocated chunk. But when you free memory in your code you usually know what size it is
//
Exclude Range from Empty list (Allocate chunk of memory)
First page is BlockHdr and cannot fit MaxPageFree
Min allocated size is 'sizeof(SEmpty)' (8 bytes)
6 times faster than HeapAlloc on Windows :)
Most allocators put a great effort in preserving size of an allocated chunk. But when you free memory in your code you usually know what size it is
Exclude Range from Empty list ( Allocate chunk of memory ) First page is BlockHdr and cannot fit MaxPageFree Min allocated size is ' sizeof ( SEmpty ) ' ( 8 bytes ) 6 times faster than HeapAlloc on Windows : ) Most allocators put a great effort in preserving size of an allocated chunk . But when you free memory in your code you usually know what size it is
void* Alloc(SIZE_T Size)
{
 if(!Size)return nullptr;  
 if(!this->Empty)   
  {
   if(!this->Resize(this->ExAllocSize(), false))return nullptr;    
  }  
 SIZE_T  FLen  = AlignFrwrdPow2(Size, BAlignment);     
 if(FLen > MaxPageFree)return nullptr;   
 SEmpty* EPrv  = nullptr;
 SEmpty* ELst  = nullptr;
 SEmpty* PCur  = nullptr;
 SEmpty* ECur  = nullptr;
 SIZE_T LSize  = -1;
 SIZE_T EmOffs = this->Empty;
 for(;;)  
  {
   ECur = (SEmpty*)((UINT8*)this + EmOffs);
   if((ECur->Size >= FLen) && (ECur->Size < LSize))   
    {
     if(ECur->Size == FLen) 
      {
       if(EmOffs == this->Empty)this->Empty = ECur->Next;  
       else if(!ECur->Next)PCur->Next = 0;  
            else PCur->Next = ECur->Next;  
       return ECur;
      }
     ELst  = ECur;
     EPrv  = PCur;
     LSize = ECur->Size;
    }
   PCur   = ECur;
   if(!ECur->Next)break;   
   EmOffs = ECur->Next;
  }
 if(!ELst)  
  {
   if(!this->Resize(this->ExAllocSize(), false))return nullptr;    
   EmOffs = LSize = PCur->Next;  
   ELst   = (SEmpty*)((UINT8*)this + EmOffs);
   EPrv   = PCur;
  }
   else EmOffs = LSize = (UINT8*)ELst - (UINT8*)this;
 EmOffs += FLen;
 ECur    = (SEmpty*)((UINT8*)this + EmOffs);
 if(LSize == this->Empty)this->Empty = EmOffs;   
   else EPrv->Next = EmOffs;
 ECur->Next = ELst->Next;
 ECur->Size = ELst->Size - FLen;
 return ELst;    
}
void * Alloc ( SIZE_T Size ) { if ( ! Size ) return nullptr ; if ( ! this -> Empty ) { if ( ! this -> Resize ( this -> ExAllocSize ( ) , false ) ) return nullptr ; } SIZE_T FLen = AlignFrwrdPow2 ( Size , BAlignment ) ; if ( FLen > MaxPageFree ) return nullptr ; SEmpty * EPrv = nullptr ; SEmpty * ELst = nullptr ; SEmpty * PCur = nullptr ; SEmpty * ECur = nullptr ; SIZE_T LSize = -1 ; SIZE_T EmOffs = this -> Empty ; for ( ; ; ) { ECur = ( SEmpty * ) ( ( UINT8 * ) this + EmOffs ) ; if ( ( ECur -> Size >= FLen ) && ( ECur -> Size < LSize ) ) { if ( ECur -> Size == FLen ) { if ( EmOffs == this -> Empty ) this -> Empty = ECur -> Next ; else if ( ! ECur -> Next ) PCur -> Next = 0 ; else PCur -> Next = ECur -> Next ; return ECur ; } ELst = ECur ; EPrv = PCur ; LSize = ECur -> Size ; } PCur = ECur ; if ( ! ECur -> Next ) break ; EmOffs = ECur -> Next ; } if ( ! ELst ) { if ( ! this -> Resize ( this -> ExAllocSize ( ) , false ) ) return nullptr ; EmOffs = LSize = PCur -> Next ; ELst = ( SEmpty * ) ( ( UINT8 * ) this + EmOffs ) ; EPrv = PCur ; } else EmOffs = LSize = ( UINT8 * ) ELst - ( UINT8 * ) this ; EmOffs += FLen ; ECur = ( SEmpty * ) ( ( UINT8 * ) this + EmOffs ) ; if ( LSize == this -> Empty ) this -> Empty = EmOffs ; else EPrv -> Next = EmOffs ; ECur -> Next = ELst -> Next ; ECur -> Size = ELst -> Size - FLen ; return ELst ; }
Exclude Range from Empty list (Allocate chunk of memory)
First page is BlockHdr and cannot fit MaxPageFree
Min allocated size is 'sizeof(SEmpty)' (8 bytes)
6 times faster than HeapAlloc on Windows :)
Most allocators put a great effort in preserving size of an allocated chunk.
Exclude Range from Empty list ( Allocate chunk of memory ) First page is BlockHdr and cannot fit MaxPageFree Min allocated size is ' sizeof ( SEmpty ) ' ( 8 bytes ) 6 times faster than HeapAlloc on Windows : ) Most allocators put a great effort in preserving size of an allocated chunk .
// ??? // No empty chunks   // After this we should have at least one free page added // Without alignment there are mem leftovers lost when left is '< sizeof(SEmpty)' in a chunk (Impossible to put in Empty list)  // Headers also aligned to this value (Min sizeof(SEmpty))  // No mem for this // Find a smallest free chunk to fit 'Size' // Exact fit // First    // 0 if this is the only // Last  // Expected to exist: 'EmOffs != this->Empty'   // Exclude // No free space found   // PERF: Additional pass through Empty list // After this we should have at least one free page added // 'Next' should be updated to point to a newly added page // First // No Zeroing?