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:
@@ -49,8 +49,8 @@ public:
|
|||||||
int32 RefCount() const
|
int32 RefCount() const
|
||||||
{ return fRefCount; }
|
{ return fRefCount; }
|
||||||
|
|
||||||
void Get() { atomic_add(&fRefCount, 1); }
|
inline void Get() { atomic_add(&fRefCount, 1); }
|
||||||
void Put();
|
inline void Put();
|
||||||
void RemoveAndPut();
|
void RemoveAndPut();
|
||||||
|
|
||||||
void IncrementFaultCount()
|
void IncrementFaultCount()
|
||||||
@@ -107,6 +107,8 @@ public:
|
|||||||
static VMAddressSpace* Get(team_id teamID);
|
static VMAddressSpace* Get(team_id teamID);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static void _DeleteIfUnreferenced(team_id id);
|
||||||
|
|
||||||
static int _DumpCommand(int argc, char** argv);
|
static int _DumpCommand(int argc, char** argv);
|
||||||
static int _DumpListCommand(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 {
|
class VMAddressSpace::AreaIterator {
|
||||||
public:
|
public:
|
||||||
AreaIterator()
|
AreaIterator()
|
||||||
|
|||||||
@@ -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
|
/*! Deletes all areas in the specified address space, and the address
|
||||||
space by decreasing all reference counters. It also marks the
|
space by decreasing all reference counters. It also marks the
|
||||||
address space of being in deletion state, so that no more areas
|
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
|
/*static*/ int
|
||||||
VMAddressSpace::_DumpCommand(int argc, char** argv)
|
VMAddressSpace::_DumpCommand(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user