VMAddressSpace::Put() is too hot to always write lock the address spaces

table. It is now inline and uses double-checked locking. This reduces the
contention on the lock to insignificant. Total -j8 Haiku image build speedup
is marginal, but the total kernel time drops 12%.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34934 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2010-01-07 14:09:56 +00:00
parent 3cd2094396
commit 8ab820f076
2 changed files with 32 additions and 19 deletions

View File

@ -49,8 +49,8 @@ public:
int32 RefCount() const
{ return fRefCount; }
void Get() { atomic_add(&fRefCount, 1); }
void Put();
inline void Get() { atomic_add(&fRefCount, 1); }
inline void Put();
void RemoveAndPut();
void IncrementFaultCount()
@ -107,6 +107,8 @@ public:
static VMAddressSpace* Get(team_id teamID);
protected:
static void _DeleteIfUnreferenced(team_id id);
static int _DumpCommand(int argc, char** argv);
static int _DumpListCommand(int argc, char** argv);
@ -129,6 +131,15 @@ protected:
};
void
VMAddressSpace::Put()
{
team_id id = fID;
if (atomic_add(&fRefCount, -1) == 1)
_DeleteIfUnreferenced(id);
}
class VMAddressSpace::AreaIterator {
public:
AreaIterator()

View File

@ -148,23 +148,6 @@ VMAddressSpace::InitPostSem()
}
void
VMAddressSpace::Put()
{
bool remove = false;
rw_lock_write_lock(&sAddressSpaceTableLock);
if (atomic_add(&fRefCount, -1) == 1) {
sAddressSpaceTable.RemoveUnchecked(this);
remove = true;
}
rw_lock_write_unlock(&sAddressSpaceTableLock);
if (remove)
delete this;
}
/*! Deletes all areas in the specified address space, and the address
space by decreasing all reference counters. It also marks the
address space of being in deletion state, so that no more areas
@ -293,6 +276,25 @@ VMAddressSpace::Get(team_id teamID)
}
/*static*/ void
VMAddressSpace::_DeleteIfUnreferenced(team_id id)
{
rw_lock_write_lock(&sAddressSpaceTableLock);
bool remove = false;
VMAddressSpace* addressSpace = sAddressSpaceTable.Lookup(id);
if (addressSpace != NULL && addressSpace->fRefCount == 0) {
sAddressSpaceTable.RemoveUnchecked(addressSpace);
remove = true;
}
rw_lock_write_unlock(&sAddressSpaceTableLock);
if (remove)
delete addressSpace;
}
/*static*/ int
VMAddressSpace::_DumpCommand(int argc, char** argv)
{