VMAddressSpace.h revision 95118262
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
20struct virtual_address_restrictions;
21
22
23struct VMAddressSpace {
24public:
25			class AreaIterator;
26
27public:
28								VMAddressSpace(team_id id, addr_t base,
29									size_t size, const char* name);
30	virtual						~VMAddressSpace();
31
32	static	status_t			Init();
33
34			team_id				ID() const				{ return fID; }
35			addr_t				Base() const			{ return fBase; }
36			addr_t				EndAddress() const		{ return fEndAddress; }
37			size_t				Size() const { return fEndAddress - fBase + 1; }
38			void				SetSize(size_t size) {
39									fEndAddress = fBase + (size - 1);
40									fFreeSpace = size; }
41
42			size_t				FreeSpace() const		{ return fFreeSpace; }
43			bool				IsBeingDeleted() const	{ return fDeleting; }
44
45			VMTranslationMap*	TranslationMap()	{ return fTranslationMap; }
46
47			status_t			ReadLock()
48									{ return rw_lock_read_lock(&fLock); }
49			void				ReadUnlock()
50									{ rw_lock_read_unlock(&fLock); }
51			status_t			WriteLock()
52									{ return rw_lock_write_lock(&fLock); }
53			void				WriteUnlock()
54									{ rw_lock_write_unlock(&fLock); }
55
56			int32				RefCount() const
57									{ return fRefCount; }
58
59	inline	void				Get()	{ atomic_add(&fRefCount, 1); }
60	inline	void 				Put();
61			void				RemoveAndPut();
62
63			void				IncrementFaultCount()
64									{ atomic_add(&fFaultCount, 1); }
65			void				IncrementChangeCount()
66									{ fChangeCount++; }
67
68	inline	bool				IsRandomizingEnabled() const
69									{ return fRandomizingEnabled; }
70	inline	void				SetRandomizingEnabled(bool enabled)
71									{ fRandomizingEnabled = enabled; }
72
73	inline	AreaIterator		GetAreaIterator();
74
75			VMAddressSpace*&	HashTableLink()	{ return fHashTableLink; }
76
77	virtual	status_t			InitObject();
78
79	virtual	VMArea*				FirstArea() const = 0;
80	virtual	VMArea*				NextArea(VMArea* area) const = 0;
81
82	virtual	VMArea*				LookupArea(addr_t address) const = 0;
83	virtual	VMArea*				CreateArea(const char* name, uint32 wiring,
84									uint32 protection,
85									uint32 allocationFlags) = 0;
86	virtual	void				DeleteArea(VMArea* area,
87									uint32 allocationFlags) = 0;
88	virtual	status_t			InsertArea(VMArea* area, size_t size,
89									const virtual_address_restrictions*
90										addressRestrictions,
91									uint32 allocationFlags, void** _address)
92										= 0;
93	virtual	void				RemoveArea(VMArea* area,
94									uint32 allocationFlags) = 0;
95
96	virtual	bool				CanResizeArea(VMArea* area, size_t newSize) = 0;
97	virtual	status_t			ResizeArea(VMArea* area, size_t newSize,
98									uint32 allocationFlags) = 0;
99	virtual	status_t			ShrinkAreaHead(VMArea* area, size_t newSize,
100									uint32 allocationFlags) = 0;
101	virtual	status_t			ShrinkAreaTail(VMArea* area, size_t newSize,
102									uint32 allocationFlags) = 0;
103
104	virtual	status_t			ReserveAddressRange(size_t size,
105									const virtual_address_restrictions*
106										addressRestrictions,
107									uint32 flags, uint32 allocationFlags,
108									void** _address) = 0;
109	virtual	status_t			UnreserveAddressRange(addr_t address,
110									size_t size, uint32 allocationFlags) = 0;
111	virtual	void				UnreserveAllAddressRanges(
112									uint32 allocationFlags) = 0;
113
114	virtual	void				Dump() const;
115
116	static	status_t			Create(team_id teamID, addr_t base, size_t size,
117									bool kernel,
118									VMAddressSpace** _addressSpace);
119
120	static	team_id				KernelID()
121									{ return sKernelAddressSpace->ID(); }
122	static	VMAddressSpace*		Kernel()
123									{ return sKernelAddressSpace; }
124	static	VMAddressSpace*		GetKernel();
125
126	static	team_id				CurrentID();
127	static	VMAddressSpace*		GetCurrent();
128
129	static	VMAddressSpace*		Get(team_id teamID);
130
131	static	VMAddressSpace*		DebugFirst();
132	static	VMAddressSpace*		DebugNext(VMAddressSpace* addressSpace);
133	static	VMAddressSpace*		DebugGet(team_id teamID);
134
135protected:
136	static	void				_DeleteIfUnreferenced(team_id id);
137
138	static	int					_DumpCommand(int argc, char** argv);
139	static	int					_DumpListCommand(int argc, char** argv);
140
141protected:
142			struct HashDefinition;
143
144protected:
145			VMAddressSpace*		fHashTableLink;
146			addr_t				fBase;
147			addr_t				fEndAddress;		// base + (size - 1)
148			size_t				fFreeSpace;
149			rw_lock				fLock;
150			team_id				fID;
151			int32				fRefCount;
152			int32				fFaultCount;
153			int32				fChangeCount;
154			VMTranslationMap*	fTranslationMap;
155			bool				fRandomizingEnabled;
156			bool				fDeleting;
157	static	VMAddressSpace*		sKernelAddressSpace;
158};
159
160
161void
162VMAddressSpace::Put()
163{
164	team_id id = fID;
165	if (atomic_add(&fRefCount, -1) == 1)
166		_DeleteIfUnreferenced(id);
167}
168
169
170class VMAddressSpace::AreaIterator {
171public:
172	AreaIterator()
173	{
174	}
175
176	AreaIterator(VMAddressSpace* addressSpace)
177		:
178		fAddressSpace(addressSpace),
179		fNext(addressSpace->FirstArea())
180	{
181	}
182
183	bool HasNext() const
184	{
185		return fNext != NULL;
186	}
187
188	VMArea* Next()
189	{
190		VMArea* result = fNext;
191		if (fNext != NULL)
192			fNext = fAddressSpace->NextArea(fNext);
193		return result;
194	}
195
196	void Rewind()
197	{
198		fNext = fAddressSpace->FirstArea();
199	}
200
201private:
202	VMAddressSpace*	fAddressSpace;
203	VMArea*			fNext;
204};
205
206
207inline VMAddressSpace::AreaIterator
208VMAddressSpace::GetAreaIterator()
209{
210	return AreaIterator(this);
211}
212
213
214#ifdef __cplusplus
215extern "C" {
216#endif
217
218void vm_delete_areas(struct VMAddressSpace *aspace, bool deletingAddressSpace);
219#define vm_swap_address_space(from, to) arch_vm_aspace_swap(from, to)
220
221#ifdef __cplusplus
222}
223#endif
224
225
226#endif	/* _KERNEL_VM_VM_ADDRESS_SPACE_H */
227