1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de. 4 * Distributed under the terms of the MIT License. 5 * 6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. 7 * Distributed under the terms of the NewOS License. 8 */ 9 10 11 #include <vm/VMArea.h> 12 13 #include <heap.h> 14 15 16 #define AREA_HASH_TABLE_SIZE 1024 17 18 19 rw_lock VMAreaHash::sLock = RW_LOCK_INITIALIZER("area hash"); 20 VMAreaHashTable VMAreaHash::sTable; 21 static area_id sNextAreaID = 1; 22 23 24 // #pragma mark - VMArea 25 26 VMArea::VMArea(VMAddressSpace* addressSpace, uint32 wiring, uint32 protection) 27 : 28 name(NULL), 29 protection(protection), 30 wiring(wiring), 31 memory_type(0), 32 cache(NULL), 33 no_cache_change(0), 34 cache_offset(0), 35 cache_type(0), 36 page_protections(NULL), 37 address_space(addressSpace), 38 cache_next(NULL), 39 cache_prev(NULL), 40 hash_next(NULL) 41 { 42 new (&mappings) VMAreaMappings; 43 } 44 45 46 VMArea::~VMArea() 47 { 48 free(page_protections); 49 free(name); 50 } 51 52 53 status_t 54 VMArea::Init(const char* name) 55 { 56 // restrict the area name to B_OS_NAME_LENGTH 57 size_t length = strlen(name) + 1; 58 if (length > B_OS_NAME_LENGTH) 59 length = B_OS_NAME_LENGTH; 60 61 // clone the name 62 this->name = (char*)malloc_nogrow(length); 63 if (this->name == NULL) 64 return B_NO_MEMORY; 65 strlcpy(this->name, name, length); 66 67 id = atomic_add(&sNextAreaID, 1); 68 return B_OK; 69 } 70 71 72 // #pragma mark - VMAreaHash 73 74 75 /*static*/ status_t 76 VMAreaHash::Init() 77 { 78 return sTable.Init(AREA_HASH_TABLE_SIZE); 79 } 80 81 82 /*static*/ VMArea* 83 VMAreaHash::Lookup(area_id id) 84 { 85 ReadLock(); 86 VMArea* area = LookupLocked(id); 87 ReadUnlock(); 88 return area; 89 } 90 91 92 /*static*/ area_id 93 VMAreaHash::Find(const char* name) 94 { 95 ReadLock(); 96 97 area_id id = B_NAME_NOT_FOUND; 98 99 // TODO: Iterating through the whole table can be very slow and the whole 100 // time we're holding the lock! Use a second hash table! 101 102 for (VMAreaHashTable::Iterator it = sTable.GetIterator(); 103 VMArea* area = it.Next();) { 104 if (strcmp(area->name, name) == 0) { 105 id = area->id; 106 break; 107 } 108 } 109 110 ReadUnlock(); 111 112 return id; 113 } 114 115 116 /*static*/ void 117 VMAreaHash::Insert(VMArea* area) 118 { 119 WriteLock(); 120 sTable.Insert(area); 121 WriteUnlock(); 122 } 123 124 125 /*static*/ void 126 VMAreaHash::Remove(VMArea* area) 127 { 128 WriteLock(); 129 sTable.Remove(area); 130 WriteUnlock(); 131 } 132