Box2d Stack Allocator

구조

고정크기로 b2_stackSize(기본값 100kb)의 메모리를 가지고 이것을 맨앞부터 쪼개서(그래서 스택기반) 사용하는 할당자이다. 구조가 단순한만큼 빠르다. 초기화에서 한번에 여러개를 할당하고 몰아서 해제하는 객체 로딩같은곳에서 사용 가능할듯하다.

할당한 순서와 정확히 반대로 해제해야 정상 작동한다. (그래야 스택답지)

const int32 b2_stackSize = 100 * 1024;	// 100k
const int32 b2_maxStackEntries = 32;
struct b2StackEntry
{
	char* data;
	int32 size;
	bool usedMalloc;
};

Stack Allocator안에는 100kb의 고정크기배열이 내장되어잇다. 사용자가 메모리를 요청하면 이를 쪼개서 반환한다. 만약 메모리가 딸리면 시스템 Malloc로 추가 메모리를 할당한다. 이것을 표현하기 위해서 b2StackEntry의 usedMalloc가 쓰인다.

Stack Allocator한개로 b2_maxStackEntries(32)개의 할당을 처리할수 잇다. 구조를 단순하게 하기위해서 이렇게 제한한듯하다

Malloc

b2StackEntry* entry = m_entries + m_entryCount;
entry->size = size;
if (m_index + size > b2_stackSize) {
	entry->data = (char*)b2Alloc(size);
	entry->usedMalloc = true;
} else {
	entry->data = m_data + m_index;
	entry->usedMalloc = false;
	m_index += size;
}
m_allocation += size;
m_maxAllocation = b2Max(m_maxAllocation, m_allocation);
++m_entryCount;
return entry->data;
  1. 남은 스택의 메모리로 요청한 메모리를 할당해줄수 잇는 경우, 스택에서 잘라서 할당해준다. 스택 정보를 갱신한다
  2. 남은 스택의 메모리로 요청한 메모리를 할당해줄수 없는 경우 동적할당으로 할당한다
  3. 할당 정보를 갱신한다(지금까지 할당한 메모리, 몇번이나 할당햇냐 같은 정보)

Free

b2StackEntry* entry = m_entries + m_entryCount - 1;
b2Assert(p == entry->data);
if (entry->usedMalloc) {
	b2Free(p);
} else {
	m_index -= entry->size;
}
m_allocation -= entry->size;
--m_entryCount;

p = NULL;
  1. 해제하려고 하는 블럭이 가장 마지막에 요청한 메모리일거라고 치고서 b2StackEntry를 얻는다
  2. assert를 사용해서 할당의 역순으로 해제하는것을 검증한다
  3. 동적할당으로 생성한것이면 free, 스택에서 사용한것이엇으면 스택top포인터의 위치를 조정한다
  4. 메모리 할당 정보를 갱신한다

comments powered by Disqus