2 * Copyright 2011, Rene Gollent, rene@gollent.com.
3 * Distributed under the terms of the MIT License.
7 #include "TeamMemoryBlockManager.h"
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
)
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()),
55 struct TeamMemoryBlockManager::MemoryBlockHashDefinition
{
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
74 MemoryBlockEntry
*& GetLink(MemoryBlockEntry
* value
) const
81 TeamMemoryBlockManager::TeamMemoryBlockManager()
89 TeamMemoryBlockManager::~TeamMemoryBlockManager()
96 TeamMemoryBlockManager::Init()
98 status_t result
= fLock
.InitCheck();
102 fActiveBlocks
= new(std::nothrow
) MemoryBlockTable();
103 if (fActiveBlocks
== NULL
)
105 ObjectDeleter
<MemoryBlockTable
> activeDeleter(fActiveBlocks
);
106 result
= fActiveBlocks
->Init();
110 fDeadBlocks
= new(std::nothrow
) DeadBlockTable();
111 if (fDeadBlocks
== NULL
)
114 activeDeleter
.Detach();
121 TeamMemoryBlockManager::GetMemoryBlock(target_addr_t address
)
123 AutoLocker
<BLocker
> lock(fLock
);
125 address
&= ~(B_PAGE_SIZE
- 1);
126 MemoryBlockEntry
* entry
= fActiveBlocks
->Lookup(address
);
128 if (entry
->block
->AcquireReference() != 0)
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);
139 ObjectDeleter
<TeamMemoryBlockOwner
> ownerDeleter(owner
);
141 TeamMemoryBlock
* block
= new(std::nothrow
) TeamMemoryBlock(address
,
145 ObjectDeleter
<TeamMemoryBlock
> blockDeleter(block
);
147 entry
= new(std::nothrow
) MemoryBlockEntry(block
);
151 ownerDeleter
.Detach();
152 blockDeleter
.Detach();
153 fActiveBlocks
->Insert(entry
);
160 TeamMemoryBlockManager::_Cleanup()
162 if (fActiveBlocks
!= NULL
) {
163 MemoryBlockEntry
* entry
= fActiveBlocks
->Clear(true);
165 while (entry
!= NULL
) {
166 MemoryBlockEntry
* next
= entry
->next
;
171 delete fActiveBlocks
;
172 fActiveBlocks
= NULL
;
178 TeamMemoryBlockManager::_MarkDeadBlock(target_addr_t address
)
180 MemoryBlockEntry
* entry
= fActiveBlocks
->Lookup(address
);
182 fActiveBlocks
->Remove(entry
);
183 fDeadBlocks
->Insert(entry
->block
);
190 TeamMemoryBlockManager::_RemoveBlock(target_addr_t address
)
192 AutoLocker
<BLocker
> lock(fLock
);
193 MemoryBlockEntry
* entry
= fActiveBlocks
->Lookup(address
);
195 fActiveBlocks
->Remove(entry
);
200 DeadBlockTable::Iterator iterator
= fDeadBlocks
->GetIterator();
201 while (iterator
.HasNext()) {
202 TeamMemoryBlock
* block
= iterator
.Next();
203 if (block
->BaseAddress() == address
) {
204 fDeadBlocks
->Remove(block
);
211 TeamMemoryBlockOwner::TeamMemoryBlockOwner(TeamMemoryBlockManager
* manager
)
213 fBlockManager(manager
)
218 TeamMemoryBlockOwner::~TeamMemoryBlockOwner()
224 TeamMemoryBlockOwner::RemoveBlock(TeamMemoryBlock
* block
)
226 fBlockManager
->_RemoveBlock(block
->BaseAddress());