headers/bsd: Add sys/queue.h.
[haiku.git] / src / kits / debugger / debug_managers / TeamMemoryBlockManager.cpp
blobae5e494596c4684b6b6b52ae82fc83604c7b3c7d
1 /*
2 * Copyright 2011, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "TeamMemoryBlockManager.h"
9 #include <new>
11 #include <AutoDeleter.h>
12 #include <AutoLocker.h>
14 #include "TeamMemoryBlock.h"
17 struct TeamMemoryBlockManager::Key {
18 target_addr_t address;
20 Key(target_addr_t address)
22 address(address)
26 uint32 HashValue() const
28 return (uint32)address;
31 bool operator==(const Key& other) const
33 return address == other.address;
38 struct TeamMemoryBlockManager::MemoryBlockEntry : Key {
39 TeamMemoryBlock* block;
40 MemoryBlockEntry* next;
42 MemoryBlockEntry(TeamMemoryBlock* block)
44 Key(block->BaseAddress()),
45 block(block)
49 ~MemoryBlockEntry()
55 struct TeamMemoryBlockManager::MemoryBlockHashDefinition {
56 typedef Key KeyType;
57 typedef MemoryBlockEntry ValueType;
59 size_t HashKey(const Key& key) const
61 return key.HashValue();
64 size_t Hash(const MemoryBlockEntry* value) const
66 return value->HashValue();
69 bool Compare(const Key& key, const MemoryBlockEntry* value) const
71 return key == *value;
74 MemoryBlockEntry*& GetLink(MemoryBlockEntry* value) const
76 return value->next;
81 TeamMemoryBlockManager::TeamMemoryBlockManager()
83 fActiveBlocks(NULL),
84 fDeadBlocks(NULL)
89 TeamMemoryBlockManager::~TeamMemoryBlockManager()
91 _Cleanup();
95 status_t
96 TeamMemoryBlockManager::Init()
98 status_t result = fLock.InitCheck();
99 if (result != B_OK)
100 return result;
102 fActiveBlocks = new(std::nothrow) MemoryBlockTable();
103 if (fActiveBlocks == NULL)
104 return B_NO_MEMORY;
105 ObjectDeleter<MemoryBlockTable> activeDeleter(fActiveBlocks);
106 result = fActiveBlocks->Init();
107 if (result != B_OK)
108 return result;
110 fDeadBlocks = new(std::nothrow) DeadBlockTable();
111 if (fDeadBlocks == NULL)
112 return B_NO_MEMORY;
114 activeDeleter.Detach();
116 return B_OK;
120 TeamMemoryBlock*
121 TeamMemoryBlockManager::GetMemoryBlock(target_addr_t address)
123 AutoLocker<BLocker> lock(fLock);
125 address &= ~(B_PAGE_SIZE - 1);
126 MemoryBlockEntry* entry = fActiveBlocks->Lookup(address);
127 if (entry != NULL) {
128 if (entry->block->AcquireReference() != 0)
129 return entry->block;
131 // this block already had its last reference released,
132 // move it to the dead list and create a new one instead.
133 _MarkDeadBlock(address);
136 TeamMemoryBlockOwner* owner = new(std::nothrow) TeamMemoryBlockOwner(this);
137 if (owner == NULL)
138 return NULL;
139 ObjectDeleter<TeamMemoryBlockOwner> ownerDeleter(owner);
141 TeamMemoryBlock* block = new(std::nothrow) TeamMemoryBlock(address,
142 owner);
143 if (block == NULL)
144 return NULL;
145 ObjectDeleter<TeamMemoryBlock> blockDeleter(block);
147 entry = new(std::nothrow) MemoryBlockEntry(block);
148 if (entry == NULL)
149 return NULL;
151 ownerDeleter.Detach();
152 blockDeleter.Detach();
153 fActiveBlocks->Insert(entry);
155 return entry->block;
159 void
160 TeamMemoryBlockManager::_Cleanup()
162 if (fActiveBlocks != NULL) {
163 MemoryBlockEntry* entry = fActiveBlocks->Clear(true);
165 while (entry != NULL) {
166 MemoryBlockEntry* next = entry->next;
167 delete entry;
168 entry = next;
171 delete fActiveBlocks;
172 fActiveBlocks = NULL;
177 void
178 TeamMemoryBlockManager::_MarkDeadBlock(target_addr_t address)
180 MemoryBlockEntry* entry = fActiveBlocks->Lookup(address);
181 if (entry != NULL) {
182 fActiveBlocks->Remove(entry);
183 fDeadBlocks->Insert(entry->block);
184 delete entry;
189 void
190 TeamMemoryBlockManager::_RemoveBlock(target_addr_t address)
192 AutoLocker<BLocker> lock(fLock);
193 MemoryBlockEntry* entry = fActiveBlocks->Lookup(address);
194 if (entry != NULL) {
195 fActiveBlocks->Remove(entry);
196 delete entry;
197 return;
200 DeadBlockTable::Iterator iterator = fDeadBlocks->GetIterator();
201 while (iterator.HasNext()) {
202 TeamMemoryBlock* block = iterator.Next();
203 if (block->BaseAddress() == address) {
204 fDeadBlocks->Remove(block);
205 break;
211 TeamMemoryBlockOwner::TeamMemoryBlockOwner(TeamMemoryBlockManager* manager)
213 fBlockManager(manager)
218 TeamMemoryBlockOwner::~TeamMemoryBlockOwner()
223 void
224 TeamMemoryBlockOwner::RemoveBlock(TeamMemoryBlock* block)
226 fBlockManager->_RemoveBlock(block->BaseAddress());