|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Mach Operating System
27: * Copyright (c) 1993-1987 Carnegie Mellon University
28: * All Rights Reserved.
29: *
30: * Permission to use, copy, modify and distribute this software and its
31: * documentation is hereby granted, provided that both the copyright
32: * notice and this permission notice appear in all copies of the
33: * software, derivative works or modified versions, and any portions
34: * thereof, and that both notices appear in supporting documentation.
35: *
36: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
37: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
38: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
39: *
40: * Carnegie Mellon requests users of this software to return to
41: *
42: * Software Distribution Coordinator or [email protected]
43: * School of Computer Science
44: * Carnegie Mellon University
45: * Pittsburgh PA 15213-3890
46: *
47: * any improvements or extensions that they make and grant Carnegie Mellon
48: * the rights to redistribute these changes.
49: */
50: /*
51: * File: vm_object.h
52: * Author: Avadis Tevanian, Jr., Michael Wayne Young
53: * Date: 1985
54: *
55: * Virtual memory object module definitions.
56: */
57:
58: #ifndef _VM_VM_OBJECT_H_
59: #define _VM_VM_OBJECT_H_
60:
61: #import <mach/features.h>
62:
63: #include <mach/kern_return.h>
64: #include <mach/boolean.h>
65: #include <mach/memory_object.h>
66: #include <mach/port.h>
67: #include <mach/vm_prot.h>
68: #include <mach/machine/vm_types.h>
69: #include <kern/queue.h>
70: #include <kern/lock.h>
71: #include <kern/assert.h>
72: #include <kern/macro_help.h>
73: #include <vm/pmap.h>
74: #if OLD_VM_CODE
75: #import <vm/vm_pager.h>
76: #endif
77:
78: #if MACH_PAGEMAP
79: #include <vm/vm_external.h>
80: #endif /* MACH_PAGEMAP */
81:
82: #if NORMA_VM
83: typedef struct xmm_obj * pager_request_t;
84: #else /* NORMA_VM */
85: #if OLD_VM_CODE
86: typedef port_t pager_request_t;
87: #else
88: typedef struct ipc_port * pager_request_t;
89: #endif
90: #endif /* NORMA_VM */
91: #define PAGER_REQUEST_NULL ((pager_request_t) 0)
92:
93: /*
94: * Types defined:
95: *
96: * vm_object_t Virtual memory object.
97: *
98: * We use "struct ipc_port *" instead of "ipc_port_t"
99: * to avoid include file circularities.
100: */
101:
102: struct vm_object {
103: queue_chain_t memq; /* Resident memory */
104: #if OLD_VM_CODE
105: queue_chain_t object_list; /* list of all objects */
106: #endif
107: decl_simple_lock_data(, Lock) /* Synchronization */
108: #if VM_OBJECT_DEBUG
109: thread_t LockHolder; /* Thread holding Lock */
110: #endif /* VM_OBJECT_DEBUG */
111: vm_size_t size; /* Object size (only valid
112: * if internal)
113: */
114:
115: int ref_count; /* Number of references */
116: int resident_page_count;
117: /* number of resident pages */
118:
119: struct vm_object *copy; /* Object that should receive
120: * a copy of my changed pages
121: */
122: struct vm_object *shadow; /* My shadow */
123: vm_offset_t shadow_offset; /* Offset into shadow */
124:
125: #if OLD_VM_CODE
126: vm_pager_t pager; /* Where to get data */
127: #else
128: struct ipc_port *pager; /* Where to get data */
129: #endif
130: vm_offset_t paging_offset; /* Offset into memory object */
131: pager_request_t pager_request; /* Where data comes back */
132: #if OLD_VM_CODE
133: vm_pager_t pager_name; /* How to identify region */
134: #else
135: struct ipc_port *pager_name; /* How to identify region */
136: #endif
137:
138: memory_object_copy_strategy_t
139: copy_strategy; /* How to handle data copy */
140:
141: unsigned int
142: absent_count; /* The number of pages that
143: * have been requested but
144: * not filled. That is, the
145: * number of pages for which
146: * the "absent" attribute is
147: * asserted.
148: */
149:
150: unsigned int /* boolean_t array */
151: all_wanted; /* Bit array of "want to be
152: * awakened" notations. See
153: * VM_OBJECT_EVENT_* items
154: * below
155: */
156:
157: unsigned int
158: paging_in_progress:16,
159: /* The memory object ports are
160: * being used (e.g., for pagein
161: * or pageout) -- don't change any
162: * of these fields (i.e., don't
163: * collapse, destroy or terminate)
164: */
165: /* boolean_t */ pager_created:1,/* Has pager ever been created? */
166: /* boolean_t */ pager_initialized:1,/* Are fields ready to use? */
167: /* boolean_t */ pager_ready:1, /* Will manager take requests? */
168:
169: /* boolean_t */ can_persist:1, /* The kernel may keep the data
170: * for this object (and rights to
171: * the memory object) after all
172: * address map references are
173: * deallocated?
174: */
175: /* boolean_t */ internal:1, /* Created by the kernel (and
176: * therefore, managed by the
177: * default memory manger)
178: */
179: /* boolean_t */ temporary:1, /* Permanent objects may be changed
180: * externally by the memory manager,
181: * and changes made in memory must
182: * be reflected back to the memory
183: * manager. Temporary objects lack
184: * both of these characteristics.
185: */
186: /* boolean_t */ alive:1, /* Not yet terminated (debug) */
187: /* boolean_t */ lock_in_progress : 1,
188: /* Is a multi-page lock
189: * request in progress?
190: */
191: /* boolean_t */ lock_restart : 1,
192: /* Should lock request in
193: * progress restart search?
194: */
195: /* boolean_t */ use_old_pageout : 1,
196: /* Use old pageout primitives?
197: */
198: /* boolean_t */ use_shared_copy : 1,/* Use shared (i.e.,
199: * delayed) copy on write */
200: /* boolean_t */ shadowed: 1; /* Shadow may exist */
201: #if OLD_VM_CODE
202: unsigned int
203: policy:16, /* Paging policy for obj */
204: /* boolean_t */ pager_creating :1, /* Pager being created? */
205: /* boolean_t */ object_destroy :1; /* Object being destroyed */
206: #endif
207: queue_chain_t cached_list; /* Attachment point for the list
208: * of objects cached as a result
209: * of their can_persist value
210: */
211: vm_offset_t last_alloc; /* last allocation offset */
212: #if MACH_PAGEMAP
213: vm_external_t existence_info;
214: #endif /* MACH_PAGEMAP */
215: };
216:
217: typedef struct vm_object *vm_object_t;
218: #define VM_OBJECT_NULL ((vm_object_t) 0)
219:
220: extern
221: vm_object_t kernel_object; /* the single kernel object */
222:
223: /*
224: * Declare procedures that operate on VM objects.
225: */
226:
227: #if OLD_VM_CODE
228: void vm_object_init ();
229: void vm_object_terminate();
230: vm_object_t vm_object_allocate();
231: void vm_object_reference();
232: void vm_object_deallocate();
233: void vm_object_pmap_copy();
234: void vm_object_pmap_remove();
235: void vm_object_page_remove();
236: void vm_object_shadow();
237: void vm_object_copy();
238: void vm_object_collapse();
239: vm_object_t vm_object_lookup();
240: port_t vm_object_name();
241: void vm_object_enter();
242: void vm_object_setpager();
243: kern_return_t vm_object_cache_object();
244: #define vm_object_cache(pager) vm_object_cache_object(vm_object_lookup(pager),TRUE)
245: #define vm_object_uncache(pager) vm_object_cache_object(vm_object_lookup(pager),FALSE)
246:
247: void vm_object_cache_clear();
248: int vm_object_cache_steal();
249: void vm_object_print();
250:
251: port_t vm_object_request_port();
252: vm_object_t vm_object_request_object();
253: #else
254: extern void vm_object_bootstrap(void);
255: extern void vm_object_init(void);
256: extern void vm_object_terminate(vm_object_t);
257: extern vm_object_t vm_object_allocate(vm_size_t);
258: extern void vm_object_reference(vm_object_t);
259: extern void vm_object_deallocate(vm_object_t);
260: extern void vm_object_pmap_protect(
261: vm_object_t object,
262: vm_offset_t offset,
263: vm_size_t size,
264: pmap_t pmap,
265: vm_offset_t pmap_start,
266: vm_prot_t prot);
267: extern void vm_object_pmap_remove(
268: vm_object_t object,
269: vm_offset_t start,
270: vm_offset_t end);
271: extern void vm_object_page_remove(
272: vm_object_t object,
273: vm_offset_t start,
274: vm_offset_t end);
275: extern void vm_object_shadow(
276: vm_object_t *object, /* in/out */
277: vm_offset_t *offset, /* in/out */
278: vm_size_t length);
279: extern void vm_object_collapse(vm_object_t);
280: extern vm_object_t vm_object_lookup(struct ipc_port *);
281: extern vm_object_t vm_object_lookup_name(struct ipc_port *);
282: extern struct ipc_port *vm_object_name(vm_object_t);
283: extern void vm_object_remove(vm_object_t);
284:
285: extern boolean_t vm_object_copy_temporary(
286: vm_object_t *_object, /* in/out */
287: vm_offset_t *_offset, /* in/out */
288: boolean_t *_src_needs_copy, /* out */
289: boolean_t *_dst_needs_copy); /* out */
290: extern kern_return_t vm_object_copy_strategically(
291: vm_object_t src_object,
292: vm_offset_t src_offset,
293: vm_size_t size,
294: vm_object_t *dst_object, /* out */
295: vm_offset_t *dst_offset, /* out */
296: boolean_t *dst_needs_copy); /* out */
297: extern kern_return_t vm_object_copy_slowly(
298: vm_object_t src_object,
299: vm_offset_t src_offset,
300: vm_size_t size,
301: boolean_t interruptible,
302: vm_object_t *_result_object); /* out */
303:
304: extern vm_object_t vm_object_enter(
305: struct ipc_port *pager,
306: vm_size_t size,
307: boolean_t internal);
308: extern void vm_object_pager_create(
309: vm_object_t object);
310: extern void vm_object_destroy(
311: struct ipc_port *pager);
312:
313: extern void vm_object_page_map(
314: vm_object_t,
315: vm_offset_t,
316: vm_size_t,
317: vm_offset_t (*)(void *, vm_offset_t),
318: void *);
319:
320: extern void vm_object_print(vm_object_t);
321:
322: extern vm_object_t vm_object_request_object(struct ipc_port *);
323:
324: /*
325: * Event waiting handling
326: */
327:
328: #define VM_OBJECT_EVENT_INITIALIZED 0
329: #define VM_OBJECT_EVENT_PAGER_READY 1
330: #define VM_OBJECT_EVENT_PAGING_IN_PROGRESS 2
331: #define VM_OBJECT_EVENT_ABSENT_COUNT 3
332: #define VM_OBJECT_EVENT_LOCK_IN_PROGRESS 4
333:
334: #define vm_object_wait(object, event, interruptible) \
335: MACRO_BEGIN \
336: (object)->all_wanted |= 1 << (event); \
337: vm_object_sleep(((vm_offset_t) object) + (event), \
338: (object), \
339: (interruptible)); \
340: MACRO_END
341:
342: #define vm_object_assert_wait(object, event, interruptible) \
343: MACRO_BEGIN \
344: (object)->all_wanted |= 1 << (event); \
345: assert_wait((event_t)(((vm_offset_t) object) + (event)), (interruptible)); \
346: MACRO_END
347:
348: #define vm_object_wakeup(object, event) \
349: MACRO_BEGIN \
350: if ((object)->all_wanted & (1 << (event))) \
351: thread_wakeup((event_t)(((vm_offset_t) object) + (event))); \
352: (object)->all_wanted &= ~(1 << (event)); \
353: MACRO_END
354:
355: /*
356: * Routines implemented as macros
357: */
358:
359: #define vm_object_paging_begin(object) \
360: ((object)->paging_in_progress++)
361:
362: #define vm_object_paging_end(object) \
363: MACRO_BEGIN \
364: assert((object)->paging_in_progress != 0); \
365: if (--(object)->paging_in_progress == 0) { \
366: vm_object_wakeup(object, \
367: VM_OBJECT_EVENT_PAGING_IN_PROGRESS); \
368: } \
369: MACRO_END
370:
371: #define vm_object_paging_wait(object, interruptible) \
372: MACRO_BEGIN \
373: while ((object)->paging_in_progress != 0) { \
374: vm_object_wait( (object), \
375: VM_OBJECT_EVENT_PAGING_IN_PROGRESS, \
376: (interruptible)); \
377: vm_object_lock(object); \
378: \
379: /*XXX if ((interruptible) && */ \
380: /*XXX (current_thread()->wait_result != THREAD_AWAKENED))*/ \
381: /*XXX break; */ \
382: } \
383: MACRO_END
384:
385: #define vm_object_absent_assert_wait(object, interruptible) \
386: MACRO_BEGIN \
387: vm_object_assert_wait( (object), \
388: VM_OBJECT_EVENT_ABSENT_COUNT, \
389: (interruptible)); \
390: MACRO_END
391:
392:
393: #define vm_object_absent_release(object) \
394: MACRO_BEGIN \
395: (object)->absent_count--; \
396: vm_object_wakeup((object), \
397: VM_OBJECT_EVENT_ABSENT_COUNT); \
398: MACRO_END
399: #endif
400:
401: /*
402: * Object locking macros (with and without debugging)
403: */
404:
405: #if VM_OBJECT_DEBUG
406: #define vm_object_lock_init(object) \
407: MACRO_BEGIN \
408: simple_lock_init(&(object)->Lock); \
409: (object)->LockHolder = 0; \
410: MACRO_END
411: #define vm_object_lock(object) \
412: MACRO_BEGIN \
413: simple_lock(&(object)->Lock); \
414: (object)->LockHolder = current_thread(); \
415: MACRO_END
416: #define vm_object_unlock(object) \
417: MACRO_BEGIN \
418: if ((object)->LockHolder != current_thread()) \
419: panic("vm_object_unlock 0x%x", (object)); \
420: (object)->LockHolder = 0; \
421: simple_unlock(&(object)->Lock); \
422: MACRO_END
423: #define vm_object_lock_try(object) \
424: (simple_lock_try(&(object)->Lock) \
425: ? ( ((object)->LockHolder = current_thread()) , TRUE) \
426: : FALSE)
427: #define vm_object_sleep(event, object, interruptible) \
428: MACRO_BEGIN \
429: if ((object)->LockHolder != current_thread()) \
430: panic("vm_object_sleep %#x", (object)); \
431: (object)->LockHolder = 0; \
432: thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
433: (interruptible)); \
434: MACRO_END
435: #define vm_object_lock_taken(object) \
436: ((object)->LockHolder == current_thread())
437: #else /* VM_OBJECT_DEBUG */
438: #define vm_object_lock_init(object) simple_lock_init(&(object)->Lock)
439: #define vm_object_lock(object) simple_lock(&(object)->Lock)
440: #define vm_object_unlock(object) simple_unlock(&(object)->Lock)
441: #define vm_object_lock_try(object) simple_lock_try(&(object)->Lock)
442: #define vm_object_sleep(event, object, interruptible) \
443: thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
444: (interruptible))
445: #define vm_object_lock_taken(object) simple_lock_taken(&(object)->Lock)
446: #endif /* VM_OBJECT_DEBUG */
447:
448: #endif /* _VM_VM_OBJECT_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.