[haiku-commits] r34450 - in haiku/trunk: headers/private/kernel/vm src/system/kernel src/system/kernel/arch/x86 src/system/kernel/vm

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Wed, 2 Dec 2009 20:55:59 +0100 (CET)

Author: bonefish
Date: 2009-12-02 20:55:59 +0100 (Wed, 02 Dec 2009)
New Revision: 34450
Changeset: http://dev.haiku-os.org/changeset/34450/haiku

Added:
   haiku/trunk/headers/private/kernel/vm/VMArea.h
   haiku/trunk/src/system/kernel/vm/VMArea.cpp
Modified:
   haiku/trunk/headers/private/kernel/vm/vm_types.h
   haiku/trunk/src/system/kernel/arch/x86/arch_debug.cpp
   haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp
   haiku/trunk/src/system/kernel/elf.cpp
   haiku/trunk/src/system/kernel/vm/Jamfile
   haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp
   haiku/trunk/src/system/kernel/vm/VMCache.cpp
   haiku/trunk/src/system/kernel/vm/vm.cpp
   haiku/trunk/src/system/kernel/vm/vm_page.cpp
Log:
Created VMArea.{h,cpp} and moved VMArea and the global area hash table (new
class VMAreaHash) there.


Added: haiku/trunk/headers/private/kernel/vm/VMArea.h
===================================================================
--- haiku/trunk/headers/private/kernel/vm/VMArea.h                              
(rev 0)
+++ haiku/trunk/headers/private/kernel/vm/VMArea.h      2009-12-02 19:55:59 UTC 
(rev 34450)
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Copyright 2002-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ *
+ * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
+ * Distributed under the terms of the NewOS License.
+ */
+#ifndef _KERNEL_VM_VM_AREA_H
+#define _KERNEL_VM_VM_AREA_H
+
+
+#include <lock.h>
+#include <util/OpenHashTable.h>
+#include <vm/vm_types.h>
+
+
+struct VMAddressSpace;
+struct VMCache;
+
+
+struct VMArea {
+       char*                                   name;
+       area_id                                 id;
+       addr_t                                  base;
+       addr_t                                  size;
+       uint32                                  protection;
+       uint16                                  wiring;
+       uint16                                  memory_type;
+
+       VMCache*                                cache;
+       vint32                                  no_cache_change;
+       off_t                                   cache_offset;
+       uint32                                  cache_type;
+       VMAreaMappings                  mappings;
+       uint8*                                  page_protections;
+
+       struct VMAddressSpace*  address_space;
+       struct VMArea*                  address_space_next;
+       struct VMArea*                  cache_next;
+       struct VMArea*                  cache_prev;
+       struct VMArea*                  hash_next;
+
+       bool ContainsAddress(addr_t address) const
+               { return address >= base && address <= base + (size - 1); }
+};
+
+
+struct VMAreaHashDefinition {
+       typedef area_id         KeyType;
+       typedef VMArea          ValueType;
+
+       size_t HashKey(area_id key) const
+       {
+               return key;
+       }
+
+       size_t Hash(const VMArea* value) const
+       {
+               return HashKey(value->id);
+       }
+
+       bool Compare(area_id key, const VMArea* value) const
+       {
+               return value->id == key;
+       }
+
+       VMArea*& GetLink(VMArea* value) const
+       {
+               return value->hash_next;
+       }
+};
+
+typedef BOpenHashTable<VMAreaHashDefinition> VMAreaHashTable;
+
+
+struct VMAreaHash {
+       static  status_t                        Init();
+
+       static  status_t                        ReadLock()
+                                                                       { 
return rw_lock_read_lock(&sLock); }
+       static  void                            ReadUnlock()
+                                                                       { 
rw_lock_read_unlock(&sLock); }
+       static  status_t                        WriteLock()
+                                                                       { 
return rw_lock_write_lock(&sLock); }
+       static  void                            WriteUnlock()
+                                                                       { 
rw_lock_write_unlock(&sLock); }
+
+       static  VMArea*                         LookupLocked(area_id id)
+                                                                       { 
return sTable.Lookup(id); }
+       static  VMArea*                         Lookup(area_id id);
+       static  area_id                         Find(const char* name);
+       static  void                            Insert(VMArea* area);
+       static  void                            Remove(VMArea* area);
+
+       static  VMAreaHashTable::Iterator GetIterator()
+                                                                       { 
return sTable.GetIterator(); }
+
+private:
+       static  rw_lock                         sLock;
+       static  VMAreaHashTable         sTable;
+};
+
+
+#endif // _KERNEL_VM_VM_AREA_H

Modified: haiku/trunk/headers/private/kernel/vm/vm_types.h
===================================================================
--- haiku/trunk/headers/private/kernel/vm/vm_types.h    2009-12-02 18:05:10 UTC 
(rev 34449)
+++ haiku/trunk/headers/private/kernel/vm/vm_types.h    2009-12-02 19:55:59 UTC 
(rev 34450)
@@ -287,31 +287,4 @@
 };
 
 
-struct VMArea {
-       char*                                   name;
-       area_id                                 id;
-       addr_t                                  base;
-       addr_t                                  size;
-       uint32                                  protection;
-       uint16                                  wiring;
-       uint16                                  memory_type;
-
-       VMCache*                                cache;
-       vint32                                  no_cache_change;
-       off_t                                   cache_offset;
-       uint32                                  cache_type;
-       VMAreaMappings                  mappings;
-       uint8*                                  page_protections;
-
-       struct VMAddressSpace*  address_space;
-       struct VMArea*                  address_space_next;
-       struct VMArea*                  cache_next;
-       struct VMArea*                  cache_prev;
-       struct VMArea*                  hash_next;
-
-       bool ContainsAddress(addr_t address) const
-               { return address >= base && address <= base + (size - 1); }
-};
-
-
 #endif // _KERNEL_VM_VM_TYPES_H

Modified: haiku/trunk/src/system/kernel/arch/x86/arch_debug.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_debug.cpp       2009-12-02 
18:05:10 UTC (rev 34449)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_debug.cpp       2009-12-02 
19:55:59 UTC (rev 34450)
@@ -23,6 +23,7 @@
 #include <vm/vm.h>
 #include <vm/vm_types.h>
 #include <vm/VMAddressSpace.h>
+#include <vm/VMArea.h>
 
 #include <arch_cpu.h>
 

Modified: haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp
===================================================================
--- haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp  2009-12-02 18:05:10 UTC 
(rev 34449)
+++ haiku/trunk/src/system/kernel/arch/x86/arch_vm.cpp  2009-12-02 19:55:59 UTC 
(rev 34450)
@@ -20,6 +20,7 @@
 #include <vm/vm_page.h>
 #include <vm/vm_priv.h>
 #include <vm/VMAddressSpace.h>
+#include <vm/VMArea.h>
 
 #include <arch/vm.h>
 #include <arch/int.h>

Modified: haiku/trunk/src/system/kernel/elf.cpp
===================================================================
--- haiku/trunk/src/system/kernel/elf.cpp       2009-12-02 18:05:10 UTC (rev 
34449)
+++ haiku/trunk/src/system/kernel/elf.cpp       2009-12-02 19:55:59 UTC (rev 
34450)
@@ -34,6 +34,7 @@
 #include <vm/vm.h>
 #include <vm/vm_types.h>
 #include <vm/VMAddressSpace.h>
+#include <vm/VMArea.h>
 
 #include <arch/cpu.h>
 #include <arch/elf.h>

Modified: haiku/trunk/src/system/kernel/vm/Jamfile
===================================================================
--- haiku/trunk/src/system/kernel/vm/Jamfile    2009-12-02 18:05:10 UTC (rev 
34449)
+++ haiku/trunk/src/system/kernel/vm/Jamfile    2009-12-02 19:55:59 UTC (rev 
34450)
@@ -11,6 +11,7 @@
        VMAddressSpace.cpp
        VMAnonymousCache.cpp
        VMAnonymousNoSwapCache.cpp
+       VMArea.cpp
        VMCache.cpp
        VMDeviceCache.cpp
        VMNullCache.cpp

Modified: haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp
===================================================================
--- haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp 2009-12-02 18:05:10 UTC 
(rev 34449)
+++ haiku/trunk/src/system/kernel/vm/VMAddressSpace.cpp 2009-12-02 19:55:59 UTC 
(rev 34450)
@@ -20,6 +20,7 @@
 #include <thread.h>
 #include <vm/vm.h>
 #include <vm/vm_priv.h>
+#include <vm/VMArea.h>
 
 
 //#define TRACE_VM

Added: haiku/trunk/src/system/kernel/vm/VMArea.cpp
===================================================================
--- haiku/trunk/src/system/kernel/vm/VMArea.cpp                         (rev 0)
+++ haiku/trunk/src/system/kernel/vm/VMArea.cpp 2009-12-02 19:55:59 UTC (rev 
34450)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <vm/VMArea.h>
+
+#include <vm/vm_priv.h>
+
+
+#define AREA_HASH_TABLE_SIZE 1024
+
+
+rw_lock VMAreaHash::sLock = RW_LOCK_INITIALIZER("area hash");
+VMAreaHashTable VMAreaHash::sTable;
+
+
+/*static*/ status_t
+VMAreaHash::Init()
+{
+       return sTable.Init(AREA_HASH_TABLE_SIZE);
+}
+
+
+/*static*/ VMArea*
+VMAreaHash::Lookup(area_id id)
+{
+       ReadLock();
+       VMArea* area = LookupLocked(id);
+       ReadUnlock();
+       return area;
+}
+
+
+/*static*/ area_id
+VMAreaHash::Find(const char* name)
+{
+       ReadLock();
+
+       area_id id = B_NAME_NOT_FOUND;
+
+       // TODO: Iterating through the whole table can be very slow and the 
whole
+       // time we're holding the lock! Use a second hash table!
+
+       for (VMAreaHashTable::Iterator it = sTable.GetIterator();
+                       VMArea* area = it.Next();) {
+               if (area->id == RESERVED_AREA_ID)
+                       continue;
+
+               if (strcmp(area->name, name) == 0) {
+                       id = area->id;
+                       break;
+               }
+       }
+
+       ReadUnlock();
+
+       return id;
+}
+
+
+/*static*/ void
+VMAreaHash::Insert(VMArea* area)
+{
+       WriteLock();
+       sTable.Insert(area);
+       WriteUnlock();
+}
+
+
+/*static*/ void
+VMAreaHash::Remove(VMArea* area)
+{
+       WriteLock();
+       sTable.Remove(area);
+       WriteUnlock();
+}

Modified: haiku/trunk/src/system/kernel/vm/VMCache.cpp
===================================================================
--- haiku/trunk/src/system/kernel/vm/VMCache.cpp        2009-12-02 18:05:10 UTC 
(rev 34449)
+++ haiku/trunk/src/system/kernel/vm/VMCache.cpp        2009-12-02 19:55:59 UTC 
(rev 34450)
@@ -27,6 +27,7 @@
 #include <vm/vm_page.h>
 #include <vm/vm_priv.h>
 #include <vm/vm_types.h>
+#include <vm/VMArea.h>
 
 
 //#define TRACE_VM_CACHE

Modified: haiku/trunk/src/system/kernel/vm/vm.cpp
===================================================================
--- haiku/trunk/src/system/kernel/vm/vm.cpp     2009-12-02 18:05:10 UTC (rev 
34449)
+++ haiku/trunk/src/system/kernel/vm/vm.cpp     2009-12-02 19:55:59 UTC (rev 
34450)
@@ -47,6 +47,7 @@
 #include <vm/vm_page.h>
 #include <vm/vm_priv.h>
 #include <vm/VMAddressSpace.h>
+#include <vm/VMArea.h>
 #include <vm/VMCache.h>
 
 #include "VMAnonymousCache.h"
@@ -190,10 +191,7 @@
 };
 
 
-#define AREA_HASH_TABLE_SIZE 1024
 static area_id sNextAreaID = 1;
-static hash_table* sAreaHash;
-static rw_lock sAreaHashLock = RW_LOCK_INITIALIZER("area hash");
 static mutex sMappingLock = MUTEX_INITIALIZER("page mappings");
 static mutex sAreaCacheLock = MUTEX_INITIALIZER("area->cache");
 
@@ -316,9 +314,7 @@
 
        fSpace->ReadLock();
 
-       rw_lock_read_lock(&sAreaHashLock);
-       area = (VMArea*)hash_lookup(sAreaHash, &areaID);
-       rw_lock_read_unlock(&sAreaHashLock);
+       area = VMAreaHash::Lookup(areaID);
 
        if (area == NULL || area->address_space != fSpace) {
                fSpace->ReadUnlock();
@@ -414,9 +410,7 @@
 
        fSpace->WriteLock();
 
-       rw_lock_read_lock(&sAreaHashLock);
-       area = (VMArea*)hash_lookup(sAreaHash, &areaID);
-       rw_lock_read_unlock(&sAreaHashLock);
+       area = VMAreaHash::Lookup(areaID);
 
        if (area == NULL || area->address_space != fSpace) {
                fSpace->WriteUnlock();
@@ -432,9 +426,9 @@
 AddressSpaceWriteLocker::SetFromArea(team_id team, area_id areaID,
        bool allowKernel, VMArea*& area)
 {
-       rw_lock_read_lock(&sAreaHashLock);
+       VMAreaHash::ReadLock();
 
-       area = (VMArea*)hash_lookup(sAreaHash, &areaID);
+       area = VMAreaHash::LookupLocked(areaID);
        if (area != NULL
                && (area->address_space->ID() == team
                        || (allowKernel && team == 
VMAddressSpace::KernelID()))) {
@@ -442,7 +436,7 @@
                fSpace->Get();
        }
 
-       rw_lock_read_unlock(&sAreaHashLock);
+       VMAreaHash::ReadUnlock();
 
        if (fSpace == NULL)
                return B_BAD_VALUE;
@@ -452,9 +446,7 @@
 
        fSpace->WriteLock();
 
-       rw_lock_read_lock(&sAreaHashLock);
-       area = (VMArea*)hash_lookup(sAreaHash, &areaID);
-       rw_lock_read_unlock(&sAreaHashLock);
+       area = VMAreaHash::Lookup(areaID);
 
        if (area == NULL) {
                fSpace->WriteUnlock();
@@ -722,9 +714,7 @@
                // lock the cache again and check whether anything has changed
 
                // check whether the area is gone in the meantime
-               rw_lock_read_lock(&sAreaHashLock);
-               area = (VMArea*)hash_lookup(sAreaHash, &areaID);
-               rw_lock_read_unlock(&sAreaHashLock);
+               area = VMAreaHash::Lookup(areaID);
 
                if (area == NULL) {
                        Unlock();
@@ -892,46 +882,20 @@
 //     #pragma mark -
 
 
-static int
-area_compare(void* _area, const void* key)
-{
-       VMArea* area = (VMArea*)_area;
-       const area_id* id = (const area_id*)key;
-
-       if (area->id == *id)
-               return 0;
-
-       return -1;
-}
-
-
-static uint32
-area_hash(void* _area, const void* key, uint32 range)
-{
-       VMArea* area = (VMArea*)_area;
-       const area_id* id = (const area_id*)key;
-
-       if (area != NULL)
-               return area->id % range;
-
-       return (uint32)*id % range;
-}
-
-
 static VMAddressSpace*
 get_address_space_by_area_id(area_id id)
 {
        VMAddressSpace* addressSpace = NULL;
 
-       rw_lock_read_lock(&sAreaHashLock);
+       VMAreaHash::ReadLock();
 
-       VMArea* area = (VMArea*)hash_lookup(sAreaHash, &id);
+       VMArea* area = VMAreaHash::LookupLocked(id);
        if (area != NULL) {
                addressSpace = area->address_space;
                addressSpace->Get();
        }
 
-       rw_lock_read_unlock(&sAreaHashLock);
+       VMAreaHash::ReadUnlock();
 
        return addressSpace;
 }
@@ -941,13 +905,13 @@
 static VMArea*
 lookup_area(VMAddressSpace* addressSpace, area_id id)
 {
-       rw_lock_read_lock(&sAreaHashLock);
+       VMAreaHash::ReadLock();
 
-       VMArea* area = (VMArea*)hash_lookup(sAreaHash, &id);
+       VMArea* area = VMAreaHash::LookupLocked(id);
        if (area != NULL && area->address_space != addressSpace)
                area = NULL;
 
-       rw_lock_read_unlock(&sAreaHashLock);
+       VMAreaHash::ReadUnlock();
 
        return area;
 }
@@ -1696,9 +1660,7 @@
                cache->Unlock();
 
        // insert the area in the global area hash table
-       rw_lock_write_lock(&sAreaHashLock);
-       hash_insert(sAreaHash, area);
-       rw_lock_write_unlock(&sAreaHashLock);
+       VMAreaHash::Insert(area);
 
        // grab a ref to the address space (the area holds this)
        addressSpace->Get();
@@ -2746,9 +2708,7 @@
 static void
 delete_area(VMAddressSpace* addressSpace, VMArea* area)
 {
-       rw_lock_write_lock(&sAreaHashLock);
-       hash_remove(sAreaHash, area);
-       rw_lock_write_unlock(&sAreaHashLock);
+       VMAreaHash::Remove(area);
 
        // At this point the area is removed from the global hash table, but
        // still exists in the area list.
@@ -3974,10 +3934,9 @@
                dump_area_struct((struct VMArea*)num, mappings);
        } else {
                // walk through the area list, looking for the arguments as a 
name
-               struct hash_iterator iter;
 
-               hash_open(sAreaHash, &iter);
-               while ((area = (VMArea*)hash_next(sAreaHash, &iter)) != NULL) {
+               VMAreaHashTable::Iterator it = VMAreaHash::GetIterator();
+               while ((area = it.Next()) != NULL) {
                        if (((mode & 4) != 0 && area->name != NULL
                                        && !strcmp(argv[index], area->name))
                                || (num != 0 && (((mode & 1) != 0 && 
(addr_t)area->id == num)
@@ -4000,7 +3959,6 @@
 dump_area_list(int argc, char** argv)
 {
        VMArea* area;
-       struct hash_iterator iter;
        const char* name = NULL;
        int32 id = 0;
 
@@ -4012,8 +3970,8 @@
 
        kprintf("addr          id  base\t\tsize    protect lock  name\n");
 
-       hash_open(sAreaHash, &iter);
-       while ((area = (VMArea*)hash_next(sAreaHash, &iter)) != NULL) {
+       VMAreaHashTable::Iterator it = VMAreaHash::GetIterator();
+       while ((area = it.Next()) != NULL) {
                if ((id != 0 && area->address_space->ID() != id)
                        || (name != NULL && strstr(area->name, name) == NULL))
                        continue;
@@ -4022,7 +3980,6 @@
                        (void*)area->base, (void*)area->size, area->protection, 
area->wiring,
                        area->name);
        }
-       hash_close(sAreaHash, &iter, false);
        return 0;
 }
 
@@ -4456,12 +4413,9 @@
        vm_cache_init(args);
 
        {
-               VMArea* area;
-               sAreaHash = hash_init(AREA_HASH_TABLE_SIZE,
-                       (addr_t)&area->hash_next - (addr_t)area,
-                       &area_compare, &area_hash);
-               if (sAreaHash == NULL)
-                       panic("vm_init: error creating aspace hash table\n");
+               status_t error = VMAreaHash::Init();
+               if (error != B_OK)
+                       panic("vm_init: error initializing area hash table\n");
        }
 
        VMAddressSpace::Init();
@@ -5898,26 +5852,7 @@
 area_id
 find_area(const char* name)
 {
-       rw_lock_read_lock(&sAreaHashLock);
-       struct hash_iterator iterator;
-       hash_open(sAreaHash, &iterator);
-
-       VMArea* area;
-       area_id id = B_NAME_NOT_FOUND;
-       while ((area = (VMArea*)hash_next(sAreaHash, &iterator)) != NULL) {
-               if (area->id == RESERVED_AREA_ID)
-                       continue;
-
-               if (!strcmp(area->name, name)) {
-                       id = area->id;
-                       break;
-               }
-       }
-
-       hash_close(sAreaHash, &iterator, false);
-       rw_lock_read_unlock(&sAreaHashLock);
-
-       return id;
+       return VMAreaHash::Find(name);
 }
 
 

Modified: haiku/trunk/src/system/kernel/vm/vm_page.cpp
===================================================================
--- haiku/trunk/src/system/kernel/vm/vm_page.cpp        2009-12-02 18:05:10 UTC 
(rev 34449)
+++ haiku/trunk/src/system/kernel/vm/vm_page.cpp        2009-12-02 19:55:59 UTC 
(rev 34450)
@@ -31,6 +31,7 @@
 #include <vm/vm_priv.h>
 #include <vm/vm_page.h>
 #include <vm/VMAddressSpace.h>
+#include <vm/VMArea.h>
 #include <vm/VMCache.h>
 
 #include "VMAnonymousCache.h"


Other related posts:

  • » [haiku-commits] r34450 - in haiku/trunk: headers/private/kernel/vm src/system/kernel src/system/kernel/arch/x86 src/system/kernel/vm - ingo_weinhold