18 #ifndef B2_SLAB_ALLOCATOR_H
19 #define B2_SLAB_ALLOCATOR_H
24 #include <Box2D/Common/b2IntrusiveList.h>
25 #include <Box2D/Common/b2FreeList.h>
27 #include <Box2D/Common/b2TrackedBlock.h>
44 Slab(uint32 numberOfItems) :
45 m_numberOfItems(numberOfItems)
47 B2_NOT_USED(m_padding);
50 b2Assert(
sizeof(*
this) == b2_mallocAlignment);
57 uint32 GetNumberOfItems()
const {
return m_numberOfItems; }
60 T* GetFirstItem()
const
62 return (T*)((uint8*)(
this + 1));
68 T* GetItemEnd()
const {
return GetFirstItem() + GetNumberOfItems(); }
72 uint32 m_numberOfItems;
74 uint8 m_padding[b2_mallocAlignment -
sizeof(uint32)];
81 m_itemsPerSlab(itemsPerSlab)
95 m_itemsPerSlab = itemsPerSlab;
99 uint32 GetItemsPerSlab()
const
101 return m_itemsPerSlab;
108 if (m_freeList.GetFreeList()->GetFreeList().IsEmpty() &&
111 return m_freeList.Allocate();
117 m_freeList.Free(
object);
124 if (!m_itemsPerSlab)
return false;
125 const uint32 slabSize =
sizeof(Slab) + (
sizeof(T) * m_itemsPerSlab);
126 void*
const memory = m_slabs.
Allocate(slabSize);
127 if (!memory)
return false;
129 Slab*
const slab =
new (BlockGetSlab(memory)) Slab(m_itemsPerSlab);
130 T* item = slab->GetFirstItem();
131 for (uint32 i = 0; i < m_itemsPerSlab; ++i, ++item)
133 m_freeList.AddToFreeList(
new (item) T);
143 while (!slabList.IsEmpty())
155 m_freeList.GetFreeList()->GetFreeList();
163 while (block != slabListTerminator)
166 Slab*
const slab = BlockGetSlab(block->
GetMemory());
170 const uint8*
const slabItemStart = (uint8*)slab->GetFirstItem();
171 const uint8*
const slabItemEnd = (uint8*)slab->GetItemEnd();
177 itemNode != freeItemListTerminator;
178 itemNode = itemNode->
GetNext())
180 const uint8* itemNodeAddress = (uint8*)itemNode;
181 if (itemNodeAddress >= slabItemStart &&
182 itemNodeAddress <= slabItemEnd)
185 if (slab->GetNumberOfItems() == freeItems)
208 void FreeSlab(Slab *
const slab)
211 const uint32 numberOfItems = slab->GetNumberOfItems();
212 T* item = slab->GetFirstItem();
213 for (uint32 i = 0; i < numberOfItems; ++i, ++item)
222 Slab* BlockGetSlab(
void *memory)
224 return (Slab*)memory;
229 T* SlabGetFirstItem(Slab* slab)
231 return (T*)(slab + 1);
239 uint32 m_itemsPerSlab;
244 #endif // B2_SLAB_ALLOCATOR_H
void * Allocate(uint32 size)
Allocate a block of size bytes using b2TrackedBlock::Allocate().
Definition: b2TrackedBlock.cpp:91
const b2TypedFreeList< T > & GetFreeList() const
Get the item allocator freelist.
Definition: b2SlabAllocator.h:201
Definition: b2SlabAllocator.h:36
~b2SlabAllocator()
Free all allocated slabs.
Definition: b2SlabAllocator.h:86
Definition: b2IntrusiveList.h:64
T * GetNext() const
Definition: b2IntrusiveList.h:294
void * GetMemory() const
Get the allocated memory associated with this block.
Definition: b2TrackedBlock.cpp:33
void SetItemsPerSlab(uint32 itemsPerSlab)
Definition: b2SlabAllocator.h:93
T * Allocate()
Allocate a item from the slab.
Definition: b2SlabAllocator.h:105
Definition: b2FreeList.h:76
b2IntrusiveListNode * GetNext() const
Get the next node in the list.
Definition: b2IntrusiveList.h:146
void Free(T *object)
Free an item from the slab.
Definition: b2SlabAllocator.h:115
void FreeEmptySlabs()
Definition: b2SlabAllocator.h:152
Allocated block of memory that can be tracked in a b2IntrusiveList.
Definition: b2TrackedBlock.h:28
const b2IntrusiveListNode * GetTerminator() const
Get the terminator of the list.
Definition: b2IntrusiveList.h:106
void FreeAllSlabs()
Free all slabs.
Definition: b2SlabAllocator.h:139
bool AllocateSlab()
Definition: b2SlabAllocator.h:122
T * GetTerminator() const
Definition: b2IntrusiveList.h:309
b2SlabAllocator(const uint32 itemsPerSlab)
Definition: b2SlabAllocator.h:80
Allocator of blocks which are tracked in a list.
Definition: b2TrackedBlock.h:62
void Free(void *memory)
Free a block returned by Allocate().
Definition: b2TrackedBlock.cpp:99