diff --git a/headers/private/kernel/vm/VMAddressSpace.h b/headers/private/kernel/vm/VMAddressSpace.h index 93b7b086ae..fd02bc6be6 100644 --- a/headers/private/kernel/vm/VMAddressSpace.h +++ b/headers/private/kernel/vm/VMAddressSpace.h @@ -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() diff --git a/src/system/kernel/vm/VMAddressSpace.cpp b/src/system/kernel/vm/VMAddressSpace.cpp index 492ccf24d4..fcaccfaa8f 100644 --- a/src/system/kernel/vm/VMAddressSpace.cpp +++ b/src/system/kernel/vm/VMAddressSpace.cpp @@ -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) {