* Various cleanups prompted by previous commit review:
- Introduce TeamMemoryBlockOwner to act as an interface for blocks to remove themselves from the manager when they expire. Consequently remove TeamMemoryBlock's direct reference to the block manager. - Simplify GetBlock() to remove unnecessary recursion. - Store dead blocks in a doubly linked list instead of another hash table. - Minor style fixes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42090 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
36986acbbd
commit
d73d70971b
@ -44,12 +44,10 @@ struct TeamMemoryBlockManager::MemoryBlockEntry : Key {
|
||||
Key(block->BaseAddress()),
|
||||
block(block)
|
||||
{
|
||||
block->AcquireReference();
|
||||
}
|
||||
|
||||
~MemoryBlockEntry()
|
||||
{
|
||||
block->ReleaseReference();
|
||||
}
|
||||
};
|
||||
|
||||
@ -109,16 +107,11 @@ TeamMemoryBlockManager::Init()
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
fDeadBlocks = new(std::nothrow) MemoryBlockTable();
|
||||
fDeadBlocks = new(std::nothrow) DeadBlockTable();
|
||||
if (fDeadBlocks == NULL)
|
||||
return B_NO_MEMORY;
|
||||
ObjectDeleter<MemoryBlockTable> deadDeleter(fDeadBlocks);
|
||||
result = fDeadBlocks->Init();
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
activeDeleter.Detach();
|
||||
deadDeleter.Detach();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -131,29 +124,34 @@ TeamMemoryBlockManager::GetMemoryBlock(target_addr_t address)
|
||||
|
||||
address &= ~B_PAGE_SIZE - 1;
|
||||
MemoryBlockEntry* entry = fActiveBlocks->Lookup(address);
|
||||
if (entry == NULL) {
|
||||
TeamMemoryBlock* block = new(std::nothrow) TeamMemoryBlock(address,
|
||||
this);
|
||||
if (block == NULL)
|
||||
return NULL;
|
||||
if (entry != NULL) {
|
||||
if (entry->block->AcquireReference() != 0)
|
||||
return entry->block;
|
||||
|
||||
entry = new(std::nothrow) MemoryBlockEntry(block);
|
||||
if (entry == NULL) {
|
||||
delete block;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fActiveBlocks->Insert(entry);
|
||||
}
|
||||
|
||||
int32 refCount = entry->block->AcquireReference();
|
||||
if (refCount == 0) {
|
||||
// this block already had its last reference released,
|
||||
// move it to the dead list and retrieve a new one instead.
|
||||
// move it to the dead list and create a new one instead.
|
||||
_MarkDeadBlock(address);
|
||||
return GetMemoryBlock(address);
|
||||
}
|
||||
|
||||
TeamMemoryBlockOwner* owner = new(std::nothrow) TeamMemoryBlockOwner(this);
|
||||
if (owner == NULL)
|
||||
return NULL;
|
||||
ObjectDeleter<TeamMemoryBlockOwner> ownerDeleter(owner);
|
||||
|
||||
TeamMemoryBlock* block = new(std::nothrow) TeamMemoryBlock(address,
|
||||
owner);
|
||||
if (block == NULL)
|
||||
return NULL;
|
||||
ObjectDeleter<TeamMemoryBlock> blockDeleter(block);
|
||||
|
||||
entry = new(std::nothrow) MemoryBlockEntry(block);
|
||||
if (entry == NULL)
|
||||
return NULL;
|
||||
|
||||
ownerDeleter.Detach();
|
||||
blockDeleter.Detach();
|
||||
fActiveBlocks->Insert(entry);
|
||||
|
||||
return entry->block;
|
||||
}
|
||||
|
||||
@ -179,11 +177,11 @@ TeamMemoryBlockManager::_Cleanup()
|
||||
void
|
||||
TeamMemoryBlockManager::_MarkDeadBlock(target_addr_t address)
|
||||
{
|
||||
AutoLocker<BLocker> lock(fLock);
|
||||
MemoryBlockEntry* entry = fActiveBlocks->Lookup(address);
|
||||
if (entry != NULL) {
|
||||
fActiveBlocks->Remove(entry);
|
||||
fDeadBlocks->Insert(entry);
|
||||
fDeadBlocks->Insert(entry->block);
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,10 +197,31 @@ TeamMemoryBlockManager::_RemoveBlock(target_addr_t address)
|
||||
return;
|
||||
}
|
||||
|
||||
entry = fDeadBlocks->Lookup(address);
|
||||
if (entry != NULL) {
|
||||
fDeadBlocks->Remove(entry);
|
||||
delete entry;
|
||||
DeadBlockTable::Iterator iterator = fDeadBlocks->GetIterator();
|
||||
while (iterator.HasNext()) {
|
||||
TeamMemoryBlock* block = iterator.Next();
|
||||
if (block->BaseAddress() == address) {
|
||||
fDeadBlocks->Remove(block);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TeamMemoryBlockOwner::TeamMemoryBlockOwner(TeamMemoryBlockManager* manager)
|
||||
:
|
||||
fBlockManager(manager)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TeamMemoryBlockOwner::~TeamMemoryBlockOwner()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TeamMemoryBlockOwner::RemoveBlock(TeamMemoryBlock* block)
|
||||
{
|
||||
fBlockManager->_RemoveBlock(block->BaseAddress());
|
||||
}
|
||||
|
@ -8,10 +8,12 @@
|
||||
|
||||
#include <Locker.h>
|
||||
#include <Referenceable.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <util/OpenHashTable.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
|
||||
struct MemoryBlockHashDefinition;
|
||||
class TeamMemoryBlock;
|
||||
|
||||
@ -31,6 +33,7 @@ private:
|
||||
struct MemoryBlockEntry;
|
||||
struct MemoryBlockHashDefinition;
|
||||
typedef BOpenHashTable<MemoryBlockHashDefinition> MemoryBlockTable;
|
||||
typedef DoublyLinkedList<TeamMemoryBlock> DeadBlockTable;
|
||||
|
||||
private:
|
||||
void _Cleanup();
|
||||
@ -38,12 +41,26 @@ private:
|
||||
void _RemoveBlock(target_addr_t address);
|
||||
|
||||
private:
|
||||
friend class TeamMemoryBlock;
|
||||
friend class TeamMemoryBlockOwner;
|
||||
|
||||
private:
|
||||
BLocker fLock;
|
||||
MemoryBlockTable* fActiveBlocks;
|
||||
MemoryBlockTable* fDeadBlocks;
|
||||
DeadBlockTable* fDeadBlocks;
|
||||
};
|
||||
|
||||
|
||||
class TeamMemoryBlockOwner
|
||||
{
|
||||
public:
|
||||
TeamMemoryBlockOwner(
|
||||
TeamMemoryBlockManager* manager);
|
||||
~TeamMemoryBlockOwner();
|
||||
|
||||
void RemoveBlock(TeamMemoryBlock* block);
|
||||
|
||||
private:
|
||||
TeamMemoryBlockManager* fBlockManager;
|
||||
};
|
||||
|
||||
|
||||
|
@ -16,17 +16,18 @@
|
||||
|
||||
|
||||
TeamMemoryBlock::TeamMemoryBlock(target_addr_t baseAddress,
|
||||
TeamMemoryBlockManager* manager)
|
||||
TeamMemoryBlockOwner* owner)
|
||||
:
|
||||
fValid(false),
|
||||
fBaseAddress(baseAddress),
|
||||
fBlockManager(manager)
|
||||
fBlockOwner(owner)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TeamMemoryBlock::~TeamMemoryBlock()
|
||||
{
|
||||
delete fBlockOwner;
|
||||
}
|
||||
|
||||
|
||||
@ -88,9 +89,9 @@ TeamMemoryBlock::NotifyDataRetrieved()
|
||||
void
|
||||
TeamMemoryBlock::LastReferenceReleased()
|
||||
{
|
||||
fBlockManager->_RemoveBlock(fBaseAddress);
|
||||
fBlockOwner->RemoveBlock(this);
|
||||
|
||||
BReferenceable::LastReferenceReleased();
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -15,16 +15,17 @@
|
||||
#include "Types.h"
|
||||
|
||||
|
||||
class TeamMemoryBlockManager;
|
||||
class TeamMemoryBlockOwner;
|
||||
|
||||
|
||||
class TeamMemoryBlock : public BReferenceable {
|
||||
class TeamMemoryBlock : public BReferenceable,
|
||||
public DoublyLinkedListLinkImpl<TeamMemoryBlock> {
|
||||
public:
|
||||
class Listener;
|
||||
|
||||
public:
|
||||
TeamMemoryBlock(target_addr_t baseAddress,
|
||||
TeamMemoryBlockManager* manager);
|
||||
TeamMemoryBlockOwner* owner);
|
||||
~TeamMemoryBlock();
|
||||
|
||||
void AddListener(Listener* listener);
|
||||
@ -52,8 +53,8 @@ private:
|
||||
target_addr_t fBaseAddress;
|
||||
uint8 fData[B_PAGE_SIZE];
|
||||
ListenerList fListeners;
|
||||
TeamMemoryBlockManager*
|
||||
fBlockManager;
|
||||
TeamMemoryBlockOwner*
|
||||
fBlockOwner;
|
||||
BLocker fLock;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user