1// BlockReferenceManager.cpp 2 3#include "AllocationInfo.h" 4#include "Block.h" 5#include "BlockAllocator.h" // only for BA_PANIC 6#include "BlockReferenceManager.h" 7#include "Debug.h" 8 9static const int kBlockReferenceTableSize = 128; 10 11// constructor 12BlockReferenceManager::BlockReferenceManager() 13 : fTables(10), 14 fFreeList(NULL) 15{ 16} 17 18// destructor 19BlockReferenceManager::~BlockReferenceManager() 20{ 21} 22 23// AllocateReference 24BlockReference * 25BlockReferenceManager::AllocateReference() 26{ 27 BlockReference *reference = NULL; 28 if (!fFreeList) 29 _AddTable(); 30 if (fFreeList) { 31 reference = fFreeList; 32 fFreeList = *(BlockReference**)fFreeList; 33 } 34 return reference; 35} 36 37// FreeReference 38void 39BlockReferenceManager::FreeReference(BlockReference *reference) 40{ 41 if (reference) { 42 *(BlockReference**)reference = fFreeList; 43 fFreeList = reference; 44 } 45} 46 47// CheckReference 48bool 49BlockReferenceManager::CheckReference(BlockReference *reference) 50{ 51 if (reference) { 52 uint32 address = (uint32)reference; 53 int32 tableCount = fTables.CountItems(); 54 for (int32 i = 0; i < tableCount; i++) { 55 Table *table = &fTables.ItemAt(i); 56 uint32 first = (uint32)table->GetReferences(); 57 uint32 last = (uint32)(table->GetReferences() + table->GetSize()); 58 if (first <= address && address < last) 59 return true; 60 } 61 } 62 FATAL(("BlockReference %p does not exist!\n", reference)); 63 BA_PANIC("BlockReference doesn't exist."); 64 return false; 65} 66 67// GetAllocationInfo 68void 69BlockReferenceManager::GetAllocationInfo(AllocationInfo &info) 70{ 71 info.AddListAllocation(fTables.GetCapacity(), sizeof(Table)); 72 int32 count = fTables.CountItems(); 73 for (int32 i = 0; i < count; i++) { 74 Table &table = fTables.ItemAt(i); 75 info.AddOtherAllocation(table.GetSize() * sizeof(BlockReference)); 76 } 77} 78 79// _AddTable 80status_t 81BlockReferenceManager::_AddTable() 82{ 83 status_t error = B_OK; 84 // add a new table 85 Table dummy; 86 if (fTables.AddItem(dummy)) { 87 int32 index = fTables.CountItems() - 1; 88 Table &table = fTables.ItemAt(index); 89 error = table.Init(kBlockReferenceTableSize); 90 if (error == B_OK) { 91 // add the references to the free list 92 uint32 count = table.GetSize(); 93 BlockReference *references = table.GetReferences(); 94 for (uint32 i = 0; i < count; i++) { 95 BlockReference *reference = references + i; 96 *(BlockReference**)reference = fFreeList; 97 fFreeList = reference; 98 } 99 } else 100 fTables.RemoveItem(index); 101 } else 102 SET_ERROR(error, B_NO_MEMORY); 103 return error; 104} 105 106 107// Table 108 109// destructor 110BlockReferenceManager::Table::~Table() 111{ 112 if (fReferences) 113 delete[] fReferences; 114} 115 116// Init 117status_t 118BlockReferenceManager::Table::Init(int32 size) 119{ 120 status_t error = (size > 0 ? B_OK : B_BAD_VALUE); 121 if (error == B_OK) { 122 fReferences = new(std::nothrow) BlockReference[size]; 123 if (fReferences) 124 fSize = size; 125 else 126 SET_ERROR(error, B_NO_MEMORY); 127 } 128 return error; 129} 130 131