* 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:
@@ -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());
|
||||||
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user