Author: bonefish Date: 2010-01-07 15:09:56 +0100 (Thu, 07 Jan 2010) New Revision: 34934 Changeset: http://dev.haiku-os.org/changeset/34934/haiku Modified: haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp Log: 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%. Modified: haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h =================================================================== --- haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h 2010-01-07 02:37:05 UTC (rev 34933) +++ haiku/trunk/headers/private/kernel/vm/VMAddressSpace.h 2010-01-07 14:09:56 UTC (rev 34934) @@ -49,8 +49,8 @@ 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 @@ 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 @@ }; +void +VMAddressSpace::Put() +{ + team_id id = fID; + if (atomic_add(&fRefCount, -1) == 1) + _DeleteIfUnreferenced(id); +} + + class VMAddressSpace::AreaIterator { public: AreaIterator() Modified: haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp =================================================================== --- haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp 2010-01-07 02:37:05 UTC (rev 34933) +++ haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp 2010-01-07 14:09:56 UTC (rev 34934) @@ -148,23 +148,6 @@ } -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 @@ } +/*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) {