1// BlockAllocator.h
2
3#ifndef BLOCK_ALLOCATOR_H
4#define BLOCK_ALLOCATOR_H
5
6#include <OS.h>
7
8#include "Block.h"
9#include "BlockReferenceManager.h"
10#include "Debug.h"
11#include "List.h"
12
13#define ENABLE_BA_PANIC	1
14#if ENABLE_BA_PANIC
15#define BA_PANIC(x)	{ PANIC(x); BlockAllocator::fPanic = true; }
16#endif
17
18class AllocationInfo;
19
20// BlockAllocator
21class BlockAllocator {
22public:
23	BlockAllocator(size_t areaSize);
24	~BlockAllocator();
25
26	status_t InitCheck() const;
27
28	BlockReference *AllocateBlock(size_t usableSize);
29	void FreeBlock(BlockReference *block);
30	BlockReference *ResizeBlock(BlockReference *block, size_t usableSize);
31
32	size_t GetAvailableBytes() const	{ return fAreaCount * fAreaSize; }
33	size_t GetFreeBytes() const			{ return fFreeBytes; }
34	size_t GetUsedBytes() const			{ return fAreaCount * fAreaSize
35												 - fFreeBytes; }
36
37public:
38	class Area;
39	class AreaBucket;
40
41	// debugging only
42	bool SanityCheck(bool deep = false) const;
43	bool CheckArea(Area *area);
44	bool CheckBlock(Block *block, size_t minSize = 0);
45	bool CheckBlock(BlockReference *reference, size_t minSize = 0);
46	void GetAllocationInfo(AllocationInfo &info);
47
48private:
49	inline Area *_AreaForBlock(Block *block);
50	Block *_AllocateBlock(size_t usableSize, bool dontCreateArea = false);
51	void _FreeBlock(Area *area, Block *block, bool freeReference);
52	inline void _RethinkAreaBucket(Area *area, AreaBucket *bucket,
53								   bool needsDefragmenting);
54	inline bool _DefragmentingRecommended();
55	bool _Defragment();
56
57private:
58	BlockReferenceManager		fReferenceManager;
59	AreaBucket					*fBuckets;
60	int32						fBucketCount;
61	size_t						fAreaSize;
62	int32						fAreaCount;
63	size_t						fFreeBytes;
64#if ENABLE_BA_PANIC
65public:
66	static bool					fPanic;
67#endif
68};
69
70#endif	// BLOCK_ALLOCATOR_H
71