* 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
+51 -32
View File
@@ -44,12 +44,10 @@ struct TeamMemoryBlockManager::MemoryBlockEntry : Key {
Key(block->BaseAddress()), Key(block->BaseAddress()),
block(block) block(block)
{ {
block->AcquireReference();
} }
~MemoryBlockEntry() ~MemoryBlockEntry()
{ {
block->ReleaseReference();
} }
}; };
@@ -109,16 +107,11 @@ TeamMemoryBlockManager::Init()
if (result != B_OK) if (result != B_OK)
return result; return result;
fDeadBlocks = new(std::nothrow) MemoryBlockTable(); fDeadBlocks = new(std::nothrow) DeadBlockTable();
if (fDeadBlocks == NULL) if (fDeadBlocks == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
ObjectDeleter<MemoryBlockTable> deadDeleter(fDeadBlocks);
result = fDeadBlocks->Init();
if (result != B_OK)
return result;
activeDeleter.Detach(); activeDeleter.Detach();
deadDeleter.Detach();
return B_OK; return B_OK;
} }
@@ -131,29 +124,34 @@ TeamMemoryBlockManager::GetMemoryBlock(target_addr_t address)
address &= ~B_PAGE_SIZE - 1; address &= ~B_PAGE_SIZE - 1;
MemoryBlockEntry* entry = fActiveBlocks->Lookup(address); MemoryBlockEntry* entry = fActiveBlocks->Lookup(address);
if (entry == NULL) { if (entry != NULL) {
TeamMemoryBlock* block = new(std::nothrow) TeamMemoryBlock(address, if (entry->block->AcquireReference() != 0)
this); return entry->block;
if (block == NULL)
return NULL;
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, // 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); _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; return entry->block;
} }
@@ -179,11 +177,11 @@ TeamMemoryBlockManager::_Cleanup()
void void
TeamMemoryBlockManager::_MarkDeadBlock(target_addr_t address) TeamMemoryBlockManager::_MarkDeadBlock(target_addr_t address)
{ {
AutoLocker<BLocker> lock(fLock);
MemoryBlockEntry* entry = fActiveBlocks->Lookup(address); MemoryBlockEntry* entry = fActiveBlocks->Lookup(address);
if (entry != NULL) { if (entry != NULL) {
fActiveBlocks->Remove(entry); fActiveBlocks->Remove(entry);
fDeadBlocks->Insert(entry); fDeadBlocks->Insert(entry->block);
delete entry;
} }
} }
@@ -199,10 +197,31 @@ TeamMemoryBlockManager::_RemoveBlock(target_addr_t address)
return; return;
} }
entry = fDeadBlocks->Lookup(address); DeadBlockTable::Iterator iterator = fDeadBlocks->GetIterator();
if (entry != NULL) { while (iterator.HasNext()) {
fDeadBlocks->Remove(entry); TeamMemoryBlock* block = iterator.Next();
delete entry; 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());
}
+19 -2
View File
@@ -8,10 +8,12 @@
#include <Locker.h> #include <Locker.h>
#include <Referenceable.h> #include <Referenceable.h>
#include <util/DoublyLinkedList.h>
#include <util/OpenHashTable.h> #include <util/OpenHashTable.h>
#include "Types.h" #include "Types.h"
struct MemoryBlockHashDefinition; struct MemoryBlockHashDefinition;
class TeamMemoryBlock; class TeamMemoryBlock;
@@ -31,6 +33,7 @@ private:
struct MemoryBlockEntry; struct MemoryBlockEntry;
struct MemoryBlockHashDefinition; struct MemoryBlockHashDefinition;
typedef BOpenHashTable<MemoryBlockHashDefinition> MemoryBlockTable; typedef BOpenHashTable<MemoryBlockHashDefinition> MemoryBlockTable;
typedef DoublyLinkedList<TeamMemoryBlock> DeadBlockTable;
private: private:
void _Cleanup(); void _Cleanup();
@@ -38,12 +41,26 @@ private:
void _RemoveBlock(target_addr_t address); void _RemoveBlock(target_addr_t address);
private: private:
friend class TeamMemoryBlock; friend class TeamMemoryBlockOwner;
private: private:
BLocker fLock; BLocker fLock;
MemoryBlockTable* fActiveBlocks; MemoryBlockTable* fActiveBlocks;
MemoryBlockTable* fDeadBlocks; DeadBlockTable* fDeadBlocks;
};
class TeamMemoryBlockOwner
{
public:
TeamMemoryBlockOwner(
TeamMemoryBlockManager* manager);
~TeamMemoryBlockOwner();
void RemoveBlock(TeamMemoryBlock* block);
private:
TeamMemoryBlockManager* fBlockManager;
}; };
+5 -4
View File
@@ -16,17 +16,18 @@
TeamMemoryBlock::TeamMemoryBlock(target_addr_t baseAddress, TeamMemoryBlock::TeamMemoryBlock(target_addr_t baseAddress,
TeamMemoryBlockManager* manager) TeamMemoryBlockOwner* owner)
: :
fValid(false), fValid(false),
fBaseAddress(baseAddress), fBaseAddress(baseAddress),
fBlockManager(manager) fBlockOwner(owner)
{ {
} }
TeamMemoryBlock::~TeamMemoryBlock() TeamMemoryBlock::~TeamMemoryBlock()
{ {
delete fBlockOwner;
} }
@@ -88,9 +89,9 @@ TeamMemoryBlock::NotifyDataRetrieved()
void void
TeamMemoryBlock::LastReferenceReleased() TeamMemoryBlock::LastReferenceReleased()
{ {
fBlockManager->_RemoveBlock(fBaseAddress); fBlockOwner->RemoveBlock(this);
BReferenceable::LastReferenceReleased(); delete this;
} }
+6 -5
View File
@@ -15,16 +15,17 @@
#include "Types.h" #include "Types.h"
class TeamMemoryBlockManager; class TeamMemoryBlockOwner;
class TeamMemoryBlock : public BReferenceable { class TeamMemoryBlock : public BReferenceable,
public DoublyLinkedListLinkImpl<TeamMemoryBlock> {
public: public:
class Listener; class Listener;
public: public:
TeamMemoryBlock(target_addr_t baseAddress, TeamMemoryBlock(target_addr_t baseAddress,
TeamMemoryBlockManager* manager); TeamMemoryBlockOwner* owner);
~TeamMemoryBlock(); ~TeamMemoryBlock();
void AddListener(Listener* listener); void AddListener(Listener* listener);
@@ -52,8 +53,8 @@ private:
target_addr_t fBaseAddress; target_addr_t fBaseAddress;
uint8 fData[B_PAGE_SIZE]; uint8 fData[B_PAGE_SIZE];
ListenerList fListeners; ListenerList fListeners;
TeamMemoryBlockManager* TeamMemoryBlockOwner*
fBlockManager; fBlockOwner;
BLocker fLock; BLocker fLock;
}; };