xref: /haiku/headers/private/kernel/vm/VMAddressSpace.h (revision 1deede7388b04dbeec5af85cae7164735ea9e70d)
1 /*
2  * Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
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 #ifndef _KERNEL_VM_VM_ADDRESS_SPACE_H
10 #define _KERNEL_VM_VM_ADDRESS_SPACE_H
11 
12 
13 #include <OS.h>
14 
15 #include <vm/vm_priv.h>
16 #include <vm/VMArea.h>
17 #include <vm/VMTranslationMap.h>
18 
19 
20 struct virtual_address_restrictions;
21 
22 
23 struct VMAddressSpace {
24 public:
25 			class AreaIterator;
26 			class AreaRangeIterator;
27 
28 public:
29 								VMAddressSpace(team_id id, addr_t base,
30 									size_t size, const char* name);
31 	virtual						~VMAddressSpace();
32 
33 	static	status_t			Init();
34 
35 			team_id				ID() const				{ return fID; }
36 			addr_t				Base() const			{ return fBase; }
37 			addr_t				EndAddress() const		{ return fEndAddress; }
38 			size_t				Size() const { return fEndAddress - fBase + 1; }
39 			size_t				FreeSpace() const		{ return fFreeSpace; }
40 			bool				IsBeingDeleted() const	{ return fDeleting; }
41 
42 			VMTranslationMap*	TranslationMap()	{ return fTranslationMap; }
43 
44 			status_t			ReadLock()
45 									{ return rw_lock_read_lock(&fLock); }
46 			void				ReadUnlock()
47 									{ rw_lock_read_unlock(&fLock); }
48 			status_t			WriteLock()
49 									{ return rw_lock_write_lock(&fLock); }
50 			void				WriteUnlock()
51 									{ rw_lock_write_unlock(&fLock); }
52 
53 			int32				RefCount() const
54 									{ return fRefCount; }
55 
56 	inline	void				Get()	{ atomic_add(&fRefCount, 1); }
57 	inline	void				Put();
58 			void				RemoveAndPut();
59 
60 			void				IncrementFaultCount()
61 									{ atomic_add(&fFaultCount, 1); }
62 			void				IncrementChangeCount()
63 									{ fChangeCount++; }
64 
65 	inline	bool				IsRandomizingEnabled() const
66 									{ return fRandomizingEnabled; }
67 	inline	void				SetRandomizingEnabled(bool enabled)
68 									{ fRandomizingEnabled = enabled; }
69 
70 	inline	AreaIterator		GetAreaIterator();
71 	inline	AreaRangeIterator	GetAreaRangeIterator(addr_t address,
72 									addr_t size);
73 
74 			VMAddressSpace*&	HashTableLink()	{ return fHashTableLink; }
75 
76 	virtual	status_t			InitObject();
77 
78 	virtual	VMArea*				FirstArea() const = 0;
79 	virtual	VMArea*				NextArea(VMArea* area) const = 0;
80 
81 	virtual	VMArea*				LookupArea(addr_t address) const = 0;
82 	virtual	VMArea*				FindClosestArea(addr_t address, bool less) const
83 									= 0;
84 	virtual	VMArea*				CreateArea(const char* name, uint32 wiring,
85 									uint32 protection,
86 									uint32 allocationFlags) = 0;
87 	virtual	void				DeleteArea(VMArea* area,
88 									uint32 allocationFlags) = 0;
89 	virtual	status_t			InsertArea(VMArea* area, size_t size,
90 									const virtual_address_restrictions*
91 										addressRestrictions,
92 									uint32 allocationFlags, void** _address)
93 										= 0;
94 	virtual	void				RemoveArea(VMArea* area,
95 									uint32 allocationFlags) = 0;
96 
97 	virtual	bool				CanResizeArea(VMArea* area, size_t newSize) = 0;
98 	virtual	status_t			ResizeArea(VMArea* area, size_t newSize,
99 									uint32 allocationFlags) = 0;
100 	virtual	status_t			ShrinkAreaHead(VMArea* area, size_t newSize,
101 									uint32 allocationFlags) = 0;
102 	virtual	status_t			ShrinkAreaTail(VMArea* area, size_t newSize,
103 									uint32 allocationFlags) = 0;
104 
105 	virtual	status_t			ReserveAddressRange(size_t size,
106 									const virtual_address_restrictions*
107 										addressRestrictions,
108 									uint32 flags, uint32 allocationFlags,
109 									void** _address) = 0;
110 	virtual	status_t			UnreserveAddressRange(addr_t address,
111 									size_t size, uint32 allocationFlags) = 0;
112 	virtual	void				UnreserveAllAddressRanges(
113 									uint32 allocationFlags) = 0;
114 
115 	virtual	void				Dump() const;
116 
117 	static	status_t			Create(team_id teamID, addr_t base, size_t size,
118 									bool kernel,
119 									VMAddressSpace** _addressSpace);
120 
121 	static	team_id				KernelID()
122 									{ return sKernelAddressSpace->ID(); }
123 	static	VMAddressSpace*		Kernel()
124 									{ return sKernelAddressSpace; }
125 	static	VMAddressSpace*		GetKernel();
126 
127 	static	team_id				CurrentID();
128 	static	VMAddressSpace*		GetCurrent();
129 
130 	static	VMAddressSpace*		Get(team_id teamID);
131 
132 	static	VMAddressSpace*		DebugFirst();
133 	static	VMAddressSpace*		DebugNext(VMAddressSpace* addressSpace);
134 	static	VMAddressSpace*		DebugGet(team_id teamID);
135 
136 protected:
137 	static	void				_DeleteIfUnreferenced(team_id id);
138 
139 	static	int					_DumpCommand(int argc, char** argv);
140 	static	int					_DumpListCommand(int argc, char** argv);
141 
142 protected:
143 			struct HashDefinition;
144 
145 protected:
146 			VMAddressSpace*		fHashTableLink;
147 			addr_t				fBase;
148 			addr_t				fEndAddress;		// base + (size - 1)
149 			size_t				fFreeSpace;
150 			rw_lock				fLock;
151 			team_id				fID;
152 			int32				fRefCount;
153 			int32				fFaultCount;
154 			int32				fChangeCount;
155 			VMTranslationMap*	fTranslationMap;
156 			bool				fRandomizingEnabled;
157 			bool				fDeleting;
158 	static	VMAddressSpace*		sKernelAddressSpace;
159 };
160 
161 
162 void
163 VMAddressSpace::Put()
164 {
165 	team_id id = fID;
166 	if (atomic_add(&fRefCount, -1) == 1)
167 		_DeleteIfUnreferenced(id);
168 }
169 
170 
171 class VMAddressSpace::AreaIterator {
172 public:
173 	AreaIterator()
174 	{
175 	}
176 
177 	AreaIterator(VMAddressSpace* addressSpace)
178 		:
179 		fAddressSpace(addressSpace),
180 		fNext(addressSpace->FirstArea())
181 	{
182 	}
183 
184 	bool HasNext() const
185 	{
186 		return fNext != NULL;
187 	}
188 
189 	VMArea* Next()
190 	{
191 		VMArea* result = fNext;
192 		if (fNext != NULL)
193 			fNext = fAddressSpace->NextArea(fNext);
194 		return result;
195 	}
196 
197 	void Rewind()
198 	{
199 		fNext = fAddressSpace->FirstArea();
200 	}
201 
202 private:
203 	VMAddressSpace*	fAddressSpace;
204 	VMArea*			fNext;
205 };
206 
207 
208 class VMAddressSpace::AreaRangeIterator : public VMAddressSpace::AreaIterator {
209 public:
210 	AreaRangeIterator()
211 	{
212 	}
213 
214 	AreaRangeIterator(VMAddressSpace* addressSpace, addr_t address, addr_t size)
215 		:
216 		fAddressSpace(addressSpace),
217 		fNext(NULL),
218 		fAddress(address),
219 		fEndAddress(address + size - 1)
220 	{
221 		Rewind();
222 	}
223 
224 	bool HasNext() const
225 	{
226 		return fNext != NULL;
227 	}
228 
229 	VMArea* Next()
230 	{
231 		VMArea* result = fNext;
232 		if (fNext != NULL) {
233 			fNext = fAddressSpace->NextArea(fNext);
234 			if (fNext != NULL && fNext->Base() > fEndAddress)
235 				fNext = NULL;
236 		}
237 
238 		return result;
239 	}
240 
241 	void Rewind()
242 	{
243 		fNext = fAddressSpace->FindClosestArea(fAddress, true);
244 		if (fNext != NULL && !fNext->ContainsAddress(fAddress))
245 			Next();
246 	}
247 
248 private:
249 	VMAddressSpace*	fAddressSpace;
250 	VMArea*			fNext;
251 	addr_t			fAddress;
252 	addr_t			fEndAddress;
253 };
254 
255 
256 inline VMAddressSpace::AreaIterator
257 VMAddressSpace::GetAreaIterator()
258 {
259 	return AreaIterator(this);
260 }
261 
262 
263 inline VMAddressSpace::AreaRangeIterator
264 VMAddressSpace::GetAreaRangeIterator(addr_t address, addr_t size)
265 {
266 	return AreaRangeIterator(this, address, size);
267 }
268 
269 
270 #ifdef __cplusplus
271 extern "C" {
272 #endif
273 
274 void vm_delete_areas(struct VMAddressSpace *aspace, bool deletingAddressSpace);
275 #define vm_swap_address_space(from, to) arch_vm_aspace_swap(from, to)
276 
277 #ifdef __cplusplus
278 }
279 #endif
280 
281 
282 #endif	/* _KERNEL_VM_VM_ADDRESS_SPACE_H */
283