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 95 status_t AddAreaCacheAndLock(area_id areaID, 96 bool writeLockThisOne, bool writeLockOthers, 97 VMArea*& _area, VMCache** _cache = NULL); 98 99 status_t Lock(); 100 void Unlock(); 101 bool IsLocked() const { return fLocked; } 102 103 void Unset(); 104 105 private: 106 struct lock_item { 107 VMAddressSpace* space; 108 bool write_lock; 109 }; 110 111 bool _ResizeIfNeeded(); 112 int32 _IndexOfAddressSpace(VMAddressSpace* space) 113 const; 114 status_t _AddAddressSpace(VMAddressSpace* space, 115 bool writeLock, VMAddressSpace** _space); 116 117 static int _CompareItems(const void* _a, const void* _b); 118 119 lock_item* fItems; 120 int32 fCapacity; 121 int32 fCount; 122 bool fLocked; 123 }; 124 125 126 inline status_t 127 MultiAddressSpaceLocker::AddTeam(team_id team, bool writeLock, 128 VMAddressSpace** _space) 129 { 130 return _AddAddressSpace(VMAddressSpace::Get(team), writeLock, _space); 131 } 132 133 134 inline status_t 135 MultiAddressSpaceLocker::AddArea(area_id area, bool writeLock, 136 VMAddressSpace** _space) 137 { 138 return _AddAddressSpace(GetAddressSpaceByAreaID(area), writeLock, _space); 139 } 140 141 142 #endif // VM_ADDRESS_SPACE_LOCKING_H 143