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