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 #ifndef VM_ADDRESS_SPACE_LOCKING_H 7 #define VM_ADDRESS_SPACE_LOCKING_H 8 9 10 #include <OS.h> 11 12 #include <vm/VMAddressSpace.h> 13 14 15 struct VMAddressSpace; 16 struct VMArea; 17 struct VMCache; 18 19 20 class AddressSpaceLockerBase { 21 public: 22 static VMAddressSpace* GetAddressSpaceByAreaID(area_id id); 23 }; 24 25 26 class AddressSpaceReadLocker : private AddressSpaceLockerBase { 27 public: 28 AddressSpaceReadLocker(team_id team); 29 AddressSpaceReadLocker(VMAddressSpace* space, 30 bool getNewReference); 31 AddressSpaceReadLocker(); 32 ~AddressSpaceReadLocker(); 33 34 status_t SetTo(team_id team); 35 void SetTo(VMAddressSpace* space, 36 bool getNewReference); 37 status_t SetFromArea(area_id areaID, VMArea*& area); 38 39 bool IsLocked() const { return fLocked; } 40 bool Lock(); 41 void Unlock(); 42 43 void Unset(); 44 45 VMAddressSpace* AddressSpace() const { return fSpace; } 46 47 private: 48 VMAddressSpace* fSpace; 49 bool fLocked; 50 }; 51 52 53 class AddressSpaceWriteLocker : private AddressSpaceLockerBase { 54 public: 55 AddressSpaceWriteLocker(team_id team); 56 AddressSpaceWriteLocker(VMAddressSpace* space, 57 bool getNewReference); 58 AddressSpaceWriteLocker(); 59 ~AddressSpaceWriteLocker(); 60 61 status_t SetTo(team_id team); 62 void SetTo(VMAddressSpace* space, 63 bool getNewReference); 64 status_t SetFromArea(area_id areaID, VMArea*& area); 65 status_t SetFromArea(team_id team, area_id areaID, 66 bool allowKernel, VMArea*& area); 67 status_t SetFromArea(team_id team, area_id areaID, 68 VMArea*& area); 69 70 bool IsLocked() const { return fLocked; } 71 void Unlock(); 72 73 void DegradeToReadLock(); 74 void Unset(); 75 76 VMAddressSpace* AddressSpace() const { return fSpace; } 77 78 private: 79 VMAddressSpace* fSpace; 80 bool fLocked; 81 bool fDegraded; 82 }; 83 84 85 class MultiAddressSpaceLocker : private AddressSpaceLockerBase { 86 public: 87 MultiAddressSpaceLocker(); 88 ~MultiAddressSpaceLocker(); 89 90 inline status_t AddTeam(team_id team, bool writeLock, 91 VMAddressSpace** _space = NULL); 92 inline status_t AddArea(area_id area, bool writeLock, 93 VMAddressSpace** _space = NULL); 94 inline status_t AddArea(VMArea* area, bool writeLock, 95 VMAddressSpace** _space = NULL); 96 97 status_t AddAreaCacheAndLock(area_id areaID, 98 bool writeLockThisOne, bool writeLockOthers, 99 VMArea*& _area, VMCache** _cache = NULL); 100 101 status_t Lock(); 102 void Unlock(); 103 bool IsLocked() const { return fLocked; } 104 105 void Unset(); 106 107 private: 108 struct lock_item { 109 VMAddressSpace* space; 110 bool write_lock; 111 }; 112 113 bool _ResizeIfNeeded(); 114 int32 _IndexOfAddressSpace(VMAddressSpace* space) 115 const; 116 status_t _AddAddressSpace(VMAddressSpace* space, 117 bool writeLock, VMAddressSpace** _space); 118 119 static int _CompareItems(const void* _a, const void* _b); 120 121 lock_item* fItems; 122 int32 fCapacity; 123 int32 fCount; 124 bool fLocked; 125 }; 126 127 128 inline status_t 129 MultiAddressSpaceLocker::AddTeam(team_id team, bool writeLock, 130 VMAddressSpace** _space) 131 { 132 return _AddAddressSpace(VMAddressSpace::Get(team), writeLock, _space); 133 } 134 135 136 inline status_t 137 MultiAddressSpaceLocker::AddArea(area_id area, bool writeLock, 138 VMAddressSpace** _space) 139 { 140 return _AddAddressSpace(GetAddressSpaceByAreaID(area), writeLock, _space); 141 } 142 143 144 inline status_t 145 MultiAddressSpaceLocker::AddArea(VMArea* area, bool writeLock, 146 VMAddressSpace** _space) 147 { 148 area->address_space->Get(); 149 return _AddAddressSpace(area->address_space, writeLock, _space); 150 } 151 152 153 #endif // VM_ADDRESS_SPACE_LOCKING_H 154