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