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