FreeBSD/Linux Kernel Cross Reference
sys/vm/vm_object.h
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993-1987 Carnegie Mellon University
4 * All Rights Reserved.
5 *
6 * Permission to use, copy, modify and distribute this software and its
7 * documentation is hereby granted, provided that both the copyright
8 * notice and this permission notice appear in all copies of the
9 * software, derivative works or modified versions, and any portions
10 * thereof, and that both notices appear in supporting documentation.
11 *
12 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15 *
16 * Carnegie Mellon requests users of this software to return to
17 *
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
22 *
23 * any improvements or extensions that they make and grant Carnegie Mellon
24 * the rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: vm_object.h,v $
29 * Revision 2.14 93/02/04 07:51:08 danner
30 * Added vm_object_page_map prototype.
31 * [93/02/02 danner]
32 *
33 * Revision 2.13 93/01/14 18:01:56 danner
34 * Added ANSI function prototypes.
35 * [92/12/29 dbg]
36 * 64bit cleanup. Fixed type of LockHolder.
37 * [92/12/01 af]
38 *
39 * Revision 2.12 92/03/10 16:30:34 jsb
40 * Added declaration of pager_request_t, which is an xmm_obj_t in NORMA_VM
41 * systems, ipc_port_t otherwise. Used to declare pager_request field.
42 * [92/03/06 14:47:27 jsb]
43 *
44 * Revision 2.11 92/02/23 19:51:18 elf
45 * Add shadowed bit to vm_object structure.
46 * [92/02/19 14:28:59 dlb]
47 *
48 * Add use_shared_copy bit to vm_object. Remove
49 * new temporary object copy strategies.
50 * [92/01/07 11:16:53 dlb]
51 *
52 * Add definitions for temporary object copy strategies.
53 * [92/01/06 16:26:07 dlb]
54 *
55 * Revision 2.9.9.1 92/02/18 19:26:04 jeffreyh
56 * Fixed references to LockHolder when VM_OBJECT_DEBUG is true
57 * [91/09/09 bernadat]
58 *
59 * Revision 2.10 92/01/14 16:48:24 rpd
60 * Added vm_object_bootstrap, vm_object_lookup_name.
61 * [91/12/31 rpd]
62 *
63 * Revision 2.9 91/08/28 11:18:50 jsb
64 * single_use --> use_old_pageout in vm_object structure.
65 * [91/07/03 14:18:59 dlb]
66 *
67 * Revision 2.8 91/06/25 10:34:39 rpd
68 * Changed mach_port_t to ipc_port_t where appropriate.
69 * [91/05/28 rpd]
70 *
71 * Revision 2.7 91/05/14 17:50:38 mrt
72 * Correcting copyright
73 *
74 * Revision 2.6 91/02/05 17:59:42 mrt
75 * Changed to new Mach copyright
76 * [91/02/01 16:33:56 mrt]
77 *
78 * Revision 2.5 90/11/05 14:34:48 rpd
79 * Added vm_object_lock_taken.
80 * [90/11/04 rpd]
81 *
82 * Revision 2.4 90/06/02 15:11:47 rpd
83 * Converted to new IPC.
84 * [90/03/26 23:17:24 rpd]
85 *
86 * Revision 2.3 90/02/22 20:06:39 dbg
87 * Changed declarations of vm_object_copy routines.
88 * [90/01/25 dbg]
89 *
90 * Revision 2.2 90/01/11 11:48:13 dbg
91 * Pick up some changes from mainline:
92 * Fix vm_object_absent_assert_wait to use vm_object_assert_wait
93 * instead of vm_object_wait. Also expanded object lock macros
94 * under VM_OBJECT_DEBUG to check LockHolder.
95 * [89/12/21 dlb]
96 *
97 * Add lock_in_progress, lock_restart fields;
98 * VM_OBJECT_EVENT_LOCK_IN_PROGRESS event.
99 * Remove vm_object_request_port().
100 * [89/08/07 mwyoung]
101 *
102 * Removed object_list.
103 * [89/08/31 19:45:22 rpd]
104 *
105 * Optimizations from NeXT: changed ref_count and
106 * resident_page_count
107 * to be shorts. Put LockHolder under VM_OBJECT_DEBUG. Also,
108 * added last_alloc field for the "deactivate-behind" optimization.
109 * [89/08/19 23:48:21 rpd]
110 *
111 * Coalesced some bit fields (pager_created, pager_initialized,
112 * pager_ready) into same longword with most others.
113 * Changes for MACH_KERNEL:
114 * . Export vm_object_copy_slowly.
115 * . Remove non-XP definitions.
116 * [89/04/28 dbg]
117 *
118 * Revision 2.1 89/08/03 16:45:44 rwd
119 * Created.
120 *
121 * Revision 2.12 89/04/18 21:26:50 mwyoung
122 * Recent history:
123 * Improved event mechanism.
124 * Added absent_count, to detect/prevent memory overcommitment.
125 *
126 * All other history has been incorporated into the documentation
127 * in this module. Also, see the history for the implementation
128 * file ("vm/vm_object.c").
129 * [89/04/18 mwyoung]
130 *
131 */
132 /*
133 * File: vm_object.h
134 * Author: Avadis Tevanian, Jr., Michael Wayne Young
135 * Date: 1985
136 *
137 * Virtual memory object module definitions.
138 */
139
140 #ifndef _VM_VM_OBJECT_H_
141 #define _VM_VM_OBJECT_H_
142
143 #include <mach_pagemap.h>
144 #include <norma_vm.h>
145
146 #include <mach/kern_return.h>
147 #include <mach/boolean.h>
148 #include <mach/memory_object.h>
149 #include <mach/port.h>
150 #include <mach/vm_prot.h>
151 #include <mach/machine/vm_types.h>
152 #include <kern/queue.h>
153 #include <kern/lock.h>
154 #include <kern/assert.h>
155 #include <kern/macro_help.h>
156 #include <vm/pmap.h>
157
158 #if MACH_PAGEMAP
159 #include <vm/vm_external.h>
160 #endif /* MACH_PAGEMAP */
161
162 #if NORMA_VM
163 typedef struct xmm_obj * pager_request_t;
164 #else /* NORMA_VM */
165 typedef struct ipc_port * pager_request_t;
166 #endif /* NORMA_VM */
167 #define PAGER_REQUEST_NULL ((pager_request_t) 0)
168
169 /*
170 * Types defined:
171 *
172 * vm_object_t Virtual memory object.
173 *
174 * We use "struct ipc_port *" instead of "ipc_port_t"
175 * to avoid include file circularities.
176 */
177
178 struct vm_object {
179 queue_chain_t memq; /* Resident memory */
180 decl_simple_lock_data(, Lock) /* Synchronization */
181 #if VM_OBJECT_DEBUG
182 thread_t LockHolder; /* Thread holding Lock */
183 #endif VM_OBJECT_DEBUG
184 vm_size_t size; /* Object size (only valid
185 * if internal)
186 */
187
188 short ref_count; /* Number of references */
189 short resident_page_count;
190 /* number of resident pages */
191
192 struct vm_object *copy; /* Object that should receive
193 * a copy of my changed pages
194 */
195 struct vm_object *shadow; /* My shadow */
196 vm_offset_t shadow_offset; /* Offset into shadow */
197
198 struct ipc_port *pager; /* Where to get data */
199 vm_offset_t paging_offset; /* Offset into memory object */
200 pager_request_t pager_request; /* Where data comes back */
201 struct ipc_port *pager_name; /* How to identify region */
202
203 memory_object_copy_strategy_t
204 copy_strategy; /* How to handle data copy */
205
206 unsigned int
207 absent_count; /* The number of pages that
208 * have been requested but
209 * not filled. That is, the
210 * number of pages for which
211 * the "absent" attribute is
212 * asserted.
213 */
214
215 unsigned int /* boolean_t array */
216 all_wanted; /* Bit array of "want to be
217 * awakened" notations. See
218 * VM_OBJECT_EVENT_* items
219 * below
220 */
221
222 unsigned int
223 paging_in_progress:16,
224 /* The memory object ports are
225 * being used (e.g., for pagein
226 * or pageout) -- don't change any
227 * of these fields (i.e., don't
228 * collapse, destroy or terminate)
229 */
230 /* boolean_t */ pager_created:1,/* Has pager ever been created? */
231 /* boolean_t */ pager_initialized:1,/* Are fields ready to use? */
232 /* boolean_t */ pager_ready:1, /* Will manager take requests? */
233
234 /* boolean_t */ can_persist:1, /* The kernel may keep the data
235 * for this object (and rights to
236 * the memory object) after all
237 * address map references are
238 * deallocated?
239 */
240 /* boolean_t */ internal:1, /* Created by the kernel (and
241 * therefore, managed by the
242 * default memory manger)
243 */
244 /* boolean_t */ temporary:1, /* Permanent objects may be changed
245 * externally by the memory manager,
246 * and changes made in memory must
247 * be reflected back to the memory
248 * manager. Temporary objects lack
249 * both of these characteristics.
250 */
251 /* boolean_t */ alive:1, /* Not yet terminated (debug) */
252 /* boolean_t */ lock_in_progress : 1,
253 /* Is a multi-page lock
254 * request in progress?
255 */
256 /* boolean_t */ lock_restart : 1,
257 /* Should lock request in
258 * progress restart search?
259 */
260 /* boolean_t */ use_old_pageout : 1,
261 /* Use old pageout primitives?
262 */
263 /* boolean_t */ use_shared_copy : 1,/* Use shared (i.e.,
264 * delayed) copy on write */
265 /* boolean_t */ shadowed: 1; /* Shadow may exist */
266
267 queue_chain_t cached_list; /* Attachment point for the list
268 * of objects cached as a result
269 * of their can_persist value
270 */
271 vm_offset_t last_alloc; /* last allocation offset */
272 #if MACH_PAGEMAP
273 vm_external_t existence_info;
274 #endif /* MACH_PAGEMAP */
275 };
276
277 typedef struct vm_object *vm_object_t;
278 #define VM_OBJECT_NULL ((vm_object_t) 0)
279
280 extern
281 vm_object_t kernel_object; /* the single kernel object */
282
283 /*
284 * Declare procedures that operate on VM objects.
285 */
286
287 extern void vm_object_bootstrap(void);
288 extern void vm_object_init(void);
289 extern void vm_object_terminate(vm_object_t);
290 extern vm_object_t vm_object_allocate(vm_size_t);
291 extern void vm_object_reference(vm_object_t);
292 extern void vm_object_deallocate(vm_object_t);
293 extern void vm_object_pmap_protect(
294 vm_object_t object,
295 vm_offset_t offset,
296 vm_size_t size,
297 pmap_t pmap,
298 vm_offset_t pmap_start,
299 vm_prot_t prot);
300 extern void vm_object_pmap_remove(
301 vm_object_t object,
302 vm_offset_t start,
303 vm_offset_t end);
304 extern void vm_object_page_remove(
305 vm_object_t object,
306 vm_offset_t start,
307 vm_offset_t end);
308 extern void vm_object_shadow(
309 vm_object_t *object, /* in/out */
310 vm_offset_t *offset, /* in/out */
311 vm_size_t length);
312 extern void vm_object_collapse(vm_object_t);
313 extern vm_object_t vm_object_lookup(struct ipc_port *);
314 extern vm_object_t vm_object_lookup_name(struct ipc_port *);
315 extern struct ipc_port *vm_object_name(vm_object_t);
316 extern void vm_object_remove(vm_object_t);
317
318 extern boolean_t vm_object_copy_temporary(
319 vm_object_t *_object, /* in/out */
320 vm_offset_t *_offset, /* in/out */
321 boolean_t *_src_needs_copy, /* out */
322 boolean_t *_dst_needs_copy); /* out */
323 extern kern_return_t vm_object_copy_strategically(
324 vm_object_t src_object,
325 vm_offset_t src_offset,
326 vm_size_t size,
327 vm_object_t *dst_object, /* out */
328 vm_offset_t *dst_offset, /* out */
329 boolean_t *dst_needs_copy); /* out */
330 extern kern_return_t vm_object_copy_slowly(
331 vm_object_t src_object,
332 vm_offset_t src_offset,
333 vm_size_t size,
334 boolean_t interruptible,
335 vm_object_t *_result_object); /* out */
336
337 extern vm_object_t vm_object_enter(
338 struct ipc_port *pager,
339 vm_size_t size,
340 boolean_t internal);
341 extern void vm_object_pager_create(
342 vm_object_t object);
343 extern void vm_object_destroy(
344 struct ipc_port *pager);
345
346 extern void vm_object_page_map(
347 vm_object_t,
348 vm_offset_t,
349 vm_size_t,
350 vm_offset_t (*)(void *, vm_offset_t),
351 void *);
352
353 extern void vm_object_print(vm_object_t);
354
355 extern vm_object_t vm_object_request_object(struct ipc_port *);
356
357 /*
358 * Event waiting handling
359 */
360
361 #define VM_OBJECT_EVENT_INITIALIZED 0
362 #define VM_OBJECT_EVENT_PAGER_READY 1
363 #define VM_OBJECT_EVENT_PAGING_IN_PROGRESS 2
364 #define VM_OBJECT_EVENT_ABSENT_COUNT 3
365 #define VM_OBJECT_EVENT_LOCK_IN_PROGRESS 4
366
367 #define vm_object_wait(object, event, interruptible) \
368 MACRO_BEGIN \
369 (object)->all_wanted |= 1 << (event); \
370 vm_object_sleep(((vm_offset_t) object) + (event), \
371 (object), \
372 (interruptible)); \
373 MACRO_END
374
375 #define vm_object_assert_wait(object, event, interruptible) \
376 MACRO_BEGIN \
377 (object)->all_wanted |= 1 << (event); \
378 assert_wait((event_t)(((vm_offset_t) object) + (event)), (interruptible)); \
379 MACRO_END
380
381 #define vm_object_wakeup(object, event) \
382 MACRO_BEGIN \
383 if ((object)->all_wanted & (1 << (event))) \
384 thread_wakeup((event_t)(((vm_offset_t) object) + (event))); \
385 (object)->all_wanted &= ~(1 << (event)); \
386 MACRO_END
387
388 /*
389 * Routines implemented as macros
390 */
391
392 #define vm_object_paging_begin(object) \
393 ((object)->paging_in_progress++)
394
395 #define vm_object_paging_end(object) \
396 MACRO_BEGIN \
397 assert((object)->paging_in_progress != 0); \
398 if (--(object)->paging_in_progress == 0) { \
399 vm_object_wakeup(object, \
400 VM_OBJECT_EVENT_PAGING_IN_PROGRESS); \
401 } \
402 MACRO_END
403
404 #define vm_object_paging_wait(object, interruptible) \
405 MACRO_BEGIN \
406 while ((object)->paging_in_progress != 0) { \
407 vm_object_wait( (object), \
408 VM_OBJECT_EVENT_PAGING_IN_PROGRESS, \
409 (interruptible)); \
410 vm_object_lock(object); \
411 \
412 /*XXX if ((interruptible) && */ \
413 /*XXX (current_thread()->wait_result != THREAD_AWAKENED))*/ \
414 /*XXX break; */ \
415 } \
416 MACRO_END
417
418 #define vm_object_absent_assert_wait(object, interruptible) \
419 MACRO_BEGIN \
420 vm_object_assert_wait( (object), \
421 VM_OBJECT_EVENT_ABSENT_COUNT, \
422 (interruptible)); \
423 MACRO_END
424
425
426 #define vm_object_absent_release(object) \
427 MACRO_BEGIN \
428 (object)->absent_count--; \
429 vm_object_wakeup((object), \
430 VM_OBJECT_EVENT_ABSENT_COUNT); \
431 MACRO_END
432
433 /*
434 * Object locking macros (with and without debugging)
435 */
436
437 #if VM_OBJECT_DEBUG
438 #define vm_object_lock_init(object) \
439 MACRO_BEGIN \
440 simple_lock_init(&(object)->Lock); \
441 (object)->LockHolder = 0; \
442 MACRO_END
443 #define vm_object_lock(object) \
444 MACRO_BEGIN \
445 simple_lock(&(object)->Lock); \
446 (object)->LockHolder = current_thread(); \
447 MACRO_END
448 #define vm_object_unlock(object) \
449 MACRO_BEGIN \
450 if ((object)->LockHolder != current_thread()) \
451 panic("vm_object_unlock 0x%x", (object)); \
452 (object)->LockHolder = 0; \
453 simple_unlock(&(object)->Lock); \
454 MACRO_END
455 #define vm_object_lock_try(object) \
456 (simple_lock_try(&(object)->Lock) \
457 ? ( ((object)->LockHolder = current_thread()) , TRUE) \
458 : FALSE)
459 #define vm_object_sleep(event, object, interruptible) \
460 MACRO_BEGIN \
461 if ((object)->LockHolder != current_thread()) \
462 panic("vm_object_sleep %#x", (object)); \
463 (object)->LockHolder = 0; \
464 thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
465 (interruptible)); \
466 MACRO_END
467 #define vm_object_lock_taken(object) \
468 ((object)->LockHolder == current_thread())
469 #else /* VM_OBJECT_DEBUG */
470 #define vm_object_lock_init(object) simple_lock_init(&(object)->Lock)
471 #define vm_object_lock(object) simple_lock(&(object)->Lock)
472 #define vm_object_unlock(object) simple_unlock(&(object)->Lock)
473 #define vm_object_lock_try(object) simple_lock_try(&(object)->Lock)
474 #define vm_object_sleep(event, object, interruptible) \
475 thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
476 (interruptible))
477 #define vm_object_lock_taken(object) simple_lock_taken(&(object)->Lock)
478 #endif /* VM_OBJECT_DEBUG */
479
480 #endif /* _VM_VM_OBJECT_H_ */
Cache object: 88970e8116dd9f4b47da2c2f9cb41346
|