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