* 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:
Rene Gollent 2011-06-10 22:20:39 +00:00
parent 36986acbbd
commit d73d70971b
4 changed files with 81 additions and 43 deletions

View File

@ -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());
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};