xref: /haiku/src/system/kernel/vm/VMAddressSpaceLocking.h (revision 1294543de9ac0eff000eaea1b18368c36435d08e)
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