1 // BlockAllocatorArea.h
3 #ifndef BLOCK_ALLOCATOR_AREA_H
4 #define BLOCK_ALLOCATOR_AREA_H
6 #include <util/DoublyLinkedList.h>
8 #include "BlockAllocator.h"
9 #include "BlockAllocatorMisc.h"
12 class BlockAllocator::Area
: public DoublyLinkedListLinkImpl
<Area
> {
14 static Area
*Create(size_t size
);
17 inline void SetBucket(AreaBucket
*bucket
) { fBucket
= bucket
; }
18 inline AreaBucket
*GetBucket() const { return fBucket
; }
20 inline Block
*GetFirstBlock() const { return fFirstBlock
; }
21 inline Block
*GetLastBlock() const { return fLastBlock
; }
23 inline TFreeBlock
*GetFirstFreeBlock() const { return fFirstFree
; }
24 inline TFreeBlock
*GetLastFreeBlock() const { return fLastFree
; }
26 inline bool IsEmpty() const { return (fUsedBlockCount
== 0); }
27 inline Block
*GetFirstUsedBlock() const;
29 static inline size_t GetMaxFreeBytesFor(size_t areaSize
);
31 inline size_t GetFreeBytes() const { return fFreeBytes
; }
32 inline bool NeedsDefragmenting() const { return (fFreeBlockCount
> 1); }
34 inline int32
GetBucketIndex();
36 Block
*AllocateBlock(size_t usableSize
, bool dontDefragment
= false);
37 void FreeBlock(Block
*block
, bool dontDefragment
= false);
38 Block
*ResizeBlock(Block
*block
, size_t newSize
,
39 bool dontDefragment
= false);
42 bool SanityCheck() const;
43 bool CheckBlock(Block
*block
, size_t minSize
= 0);
46 inline size_t _GetBlockFreeBytes()
47 { return fFreeBytes
+ sizeof(BlockHeader
); }
49 Area(area_id id
, size_t size
);
52 inline void _FixBlockList(Block
*block
, Block
*prevBlock
,
54 inline void _FixFreeList(TFreeBlock
*block
, TFreeBlock
*prevFree
,
55 TFreeBlock
*nextFree
);
57 TFreeBlock
*_FindFreeBlock(size_t minSize
);
58 void _InsertFreeBlock(TFreeBlock
*block
);
59 void _RemoveFreeBlock(TFreeBlock
*block
);
60 TFreeBlock
* _MoveResizeFreeBlock(TFreeBlock
*freeBlock
, ssize_t offset
,
62 inline TFreeBlock
*_MakeFreeBlock(void *address
, ssize_t offset
,
63 Block
*previous
, size_t size
, bool hasNext
, TFreeBlock
*previousFree
,
64 TFreeBlock
*nextFree
);
65 bool _CoalesceWithNext(TFreeBlock
*block
);
67 inline Block
*_MakeUsedBlock(void *address
, ssize_t offset
,
68 Block
*previous
, size_t size
, bool hasNext
);
70 inline bool _DefragmentingRecommended();
78 size_t fFreeBlockCount
;
79 size_t fUsedBlockCount
;
82 TFreeBlock
*fFirstFree
;
83 TFreeBlock
*fLastFree
;
86 typedef BlockAllocator::Area Area
;
97 BlockAllocator::Area::GetFirstUsedBlock() const
100 // 1) There is always a first block. If that isn't so, our structure are
102 // 2) If the first block is free, the second (if any) is not. Otherwise
103 // there were adjoining free blocks, which our coalescing strategy
105 return (fFirstBlock
->IsFree() ? fFirstBlock
->GetNextBlock() : fFirstBlock
);
108 // GetMaxFreeBytesFor
111 BlockAllocator::Area::GetMaxFreeBytesFor(size_t areaSize
)
113 size_t headerSize
= block_align_ceil(sizeof(Area
));
114 return Block::GetUsableSizeFor(block_align_floor(areaSize
- headerSize
));
120 BlockAllocator::Area::GetBucketIndex()
122 return bucket_containing_size(GetFreeBytes());
128 BlockAllocator::Area::_FixBlockList(Block
*block
, Block
*prevBlock
,
133 prevBlock
->SetNextBlock(block
);
137 nextBlock
->SetPreviousBlock(block
);
146 BlockAllocator::Area::_FixFreeList(TFreeBlock
*block
, TFreeBlock
*prevFree
,
147 TFreeBlock
*nextFree
)
151 prevFree
->SetNextFreeBlock(block
);
155 nextFree
->SetPreviousFreeBlock(block
);
158 block
->SetPreviousFreeBlock(prevFree
);
159 block
->SetNextFreeBlock(nextFree
);
163 // _DefragmentingRecommended
166 BlockAllocator::Area::_DefragmentingRecommended()
168 // Defragmenting Condition: At least more than 5 free blocks and
169 // free / block ratio greater 1 / 10. Don't know, if that makes any
171 return (fFreeBlockCount
> 5 && fUsedBlockCount
/ fFreeBlockCount
< 10);
174 #endif // BA_DEFINE_INLINES
177 #endif // BLOCK_ALLOCATOR_AREA_H