|
|
1.1 root 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 [email protected]
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: * File: vm_object.h
28: * Author: Avadis Tevanian, Jr., Michael Wayne Young
29: * Date: 1985
30: *
31: * Virtual memory object module definitions.
32: */
33:
34: #ifndef _VM_VM_OBJECT_H_
35: #define _VM_VM_OBJECT_H_
36:
37: #include <mach_pagemap.h>
38: #include <norma_vm.h>
39:
40: #include <mach/kern_return.h>
41: #include <mach/boolean.h>
42: #include <mach/memory_object.h>
43: #include <mach/port.h>
44: #include <mach/vm_prot.h>
45: #include <mach/machine/vm_types.h>
46: #include <kern/queue.h>
47: #include <kern/lock.h>
48: #include <kern/assert.h>
49: #include <kern/macro_help.h>
50: #include <vm/pmap.h>
51:
52: #if MACH_PAGEMAP
53: #include <vm/vm_external.h>
54: #endif /* MACH_PAGEMAP */
55:
56: #if NORMA_VM
57: typedef struct xmm_obj * pager_request_t;
58: #else /* NORMA_VM */
59: typedef struct ipc_port * pager_request_t;
60: #endif /* NORMA_VM */
61: #define PAGER_REQUEST_NULL ((pager_request_t) 0)
62:
63: /*
64: * Types defined:
65: *
66: * vm_object_t Virtual memory object.
67: *
68: * We use "struct ipc_port *" instead of "ipc_port_t"
69: * to avoid include file circularities.
70: */
71:
72: struct vm_object {
73: queue_chain_t memq; /* Resident memory */
74: decl_simple_lock_data(, Lock) /* Synchronization */
75: #if VM_OBJECT_DEBUG
76: thread_t LockHolder; /* Thread holding Lock */
77: #endif /* VM_OBJECT_DEBUG */
78: vm_size_t size; /* Object size (only valid
79: * if internal)
80: */
81:
82: short ref_count; /* Number of references */
83: short resident_page_count;
84: /* number of resident pages */
85:
86: struct vm_object *copy; /* Object that should receive
87: * a copy of my changed pages
88: */
89: struct vm_object *shadow; /* My shadow */
90: vm_offset_t shadow_offset; /* Offset into shadow */
91:
92: struct ipc_port *pager; /* Where to get data */
93: vm_offset_t paging_offset; /* Offset into memory object */
94: pager_request_t pager_request; /* Where data comes back */
95: struct ipc_port *pager_name; /* How to identify region */
96:
97: memory_object_copy_strategy_t
98: copy_strategy; /* How to handle data copy */
99:
100: unsigned int
101: absent_count; /* The number of pages that
102: * have been requested but
103: * not filled. That is, the
104: * number of pages for which
105: * the "absent" attribute is
106: * asserted.
107: */
108:
109: unsigned int /* boolean_t array */
110: all_wanted; /* Bit array of "want to be
111: * awakened" notations. See
112: * VM_OBJECT_EVENT_* items
113: * below
114: */
115:
116: unsigned int
117: paging_in_progress:16,
118: /* The memory object ports are
119: * being used (e.g., for pagein
120: * or pageout) -- don't change any
121: * of these fields (i.e., don't
122: * collapse, destroy or terminate)
123: */
124: /* boolean_t */ pager_created:1,/* Has pager ever been created? */
125: /* boolean_t */ pager_initialized:1,/* Are fields ready to use? */
126: /* boolean_t */ pager_ready:1, /* Will manager take requests? */
127:
128: /* boolean_t */ can_persist:1, /* The kernel may keep the data
129: * for this object (and rights to
130: * the memory object) after all
131: * address map references are
132: * deallocated?
133: */
134: /* boolean_t */ internal:1, /* Created by the kernel (and
135: * therefore, managed by the
136: * default memory manger)
137: */
138: /* boolean_t */ temporary:1, /* Permanent objects may be changed
139: * externally by the memory manager,
140: * and changes made in memory must
141: * be reflected back to the memory
142: * manager. Temporary objects lack
143: * both of these characteristics.
144: */
145: /* boolean_t */ alive:1, /* Not yet terminated (debug) */
146: /* boolean_t */ lock_in_progress : 1,
147: /* Is a multi-page lock
148: * request in progress?
149: */
150: /* boolean_t */ lock_restart : 1,
151: /* Should lock request in
152: * progress restart search?
153: */
154: /* boolean_t */ use_old_pageout : 1,
155: /* Use old pageout primitives?
156: */
157: /* boolean_t */ use_shared_copy : 1,/* Use shared (i.e.,
158: * delayed) copy on write */
159: /* boolean_t */ shadowed: 1; /* Shadow may exist */
160:
161: queue_chain_t cached_list; /* Attachment point for the list
162: * of objects cached as a result
163: * of their can_persist value
164: */
165: vm_offset_t last_alloc; /* last allocation offset */
166: #if MACH_PAGEMAP
167: vm_external_t existence_info;
168: #endif /* MACH_PAGEMAP */
169: };
170:
171: typedef struct vm_object *vm_object_t;
172: #define VM_OBJECT_NULL ((vm_object_t) 0)
173:
174: extern
175: vm_object_t kernel_object; /* the single kernel object */
176:
177: /*
178: * Declare procedures that operate on VM objects.
179: */
180:
181: extern void vm_object_bootstrap(void);
182: extern void vm_object_init(void);
183: extern void vm_object_terminate(vm_object_t);
184: extern vm_object_t vm_object_allocate(vm_size_t);
185: extern void vm_object_reference(vm_object_t);
186: extern void vm_object_deallocate(vm_object_t);
187: extern void vm_object_pmap_protect(
188: vm_object_t object,
189: vm_offset_t offset,
190: vm_size_t size,
191: pmap_t pmap,
192: vm_offset_t pmap_start,
193: vm_prot_t prot);
194: extern void vm_object_pmap_remove(
195: vm_object_t object,
196: vm_offset_t start,
197: vm_offset_t end);
198: extern void vm_object_page_remove(
199: vm_object_t object,
200: vm_offset_t start,
201: vm_offset_t end);
202: extern void vm_object_shadow(
203: vm_object_t *object, /* in/out */
204: vm_offset_t *offset, /* in/out */
205: vm_size_t length);
206: extern void vm_object_collapse(vm_object_t);
207: extern vm_object_t vm_object_lookup(struct ipc_port *);
208: extern vm_object_t vm_object_lookup_name(struct ipc_port *);
209: extern struct ipc_port *vm_object_name(vm_object_t);
210: extern void vm_object_remove(vm_object_t);
211:
212: extern boolean_t vm_object_copy_temporary(
213: vm_object_t *_object, /* in/out */
214: vm_offset_t *_offset, /* in/out */
215: boolean_t *_src_needs_copy, /* out */
216: boolean_t *_dst_needs_copy); /* out */
217: extern kern_return_t vm_object_copy_strategically(
218: vm_object_t src_object,
219: vm_offset_t src_offset,
220: vm_size_t size,
221: vm_object_t *dst_object, /* out */
222: vm_offset_t *dst_offset, /* out */
223: boolean_t *dst_needs_copy); /* out */
224: extern kern_return_t vm_object_copy_slowly(
225: vm_object_t src_object,
226: vm_offset_t src_offset,
227: vm_size_t size,
228: boolean_t interruptible,
229: vm_object_t *_result_object); /* out */
230:
231: extern vm_object_t vm_object_enter(
232: struct ipc_port *pager,
233: vm_size_t size,
234: boolean_t internal);
235: extern void vm_object_pager_create(
236: vm_object_t object);
237: extern void vm_object_destroy(
238: struct ipc_port *pager);
239:
240: extern void vm_object_page_map(
241: vm_object_t,
242: vm_offset_t,
243: vm_size_t,
244: vm_offset_t (*)(void *, vm_offset_t),
245: void *);
246:
247: extern void vm_object_print(vm_object_t);
248:
249: extern vm_object_t vm_object_request_object(struct ipc_port *);
250:
251: /*
252: * Event waiting handling
253: */
254:
255: #define VM_OBJECT_EVENT_INITIALIZED 0
256: #define VM_OBJECT_EVENT_PAGER_READY 1
257: #define VM_OBJECT_EVENT_PAGING_IN_PROGRESS 2
258: #define VM_OBJECT_EVENT_ABSENT_COUNT 3
259: #define VM_OBJECT_EVENT_LOCK_IN_PROGRESS 4
260:
261: #define vm_object_wait(object, event, interruptible) \
262: MACRO_BEGIN \
263: (object)->all_wanted |= 1 << (event); \
264: vm_object_sleep(((vm_offset_t) object) + (event), \
265: (object), \
266: (interruptible)); \
267: MACRO_END
268:
269: #define vm_object_assert_wait(object, event, interruptible) \
270: MACRO_BEGIN \
271: (object)->all_wanted |= 1 << (event); \
272: assert_wait((event_t)(((vm_offset_t) object) + (event)), (interruptible)); \
273: MACRO_END
274:
275: #define vm_object_wakeup(object, event) \
276: MACRO_BEGIN \
277: if ((object)->all_wanted & (1 << (event))) \
278: thread_wakeup((event_t)(((vm_offset_t) object) + (event))); \
279: (object)->all_wanted &= ~(1 << (event)); \
280: MACRO_END
281:
282: /*
283: * Routines implemented as macros
284: */
285:
286: #define vm_object_paging_begin(object) \
287: ((object)->paging_in_progress++)
288:
289: #define vm_object_paging_end(object) \
290: MACRO_BEGIN \
291: assert((object)->paging_in_progress != 0); \
292: if (--(object)->paging_in_progress == 0) { \
293: vm_object_wakeup(object, \
294: VM_OBJECT_EVENT_PAGING_IN_PROGRESS); \
295: } \
296: MACRO_END
297:
298: #define vm_object_paging_wait(object, interruptible) \
299: MACRO_BEGIN \
300: while ((object)->paging_in_progress != 0) { \
301: vm_object_wait( (object), \
302: VM_OBJECT_EVENT_PAGING_IN_PROGRESS, \
303: (interruptible)); \
304: vm_object_lock(object); \
305: \
306: /*XXX if ((interruptible) && */ \
307: /*XXX (current_thread()->wait_result != THREAD_AWAKENED))*/ \
308: /*XXX break; */ \
309: } \
310: MACRO_END
311:
312: #define vm_object_absent_assert_wait(object, interruptible) \
313: MACRO_BEGIN \
314: vm_object_assert_wait( (object), \
315: VM_OBJECT_EVENT_ABSENT_COUNT, \
316: (interruptible)); \
317: MACRO_END
318:
319:
320: #define vm_object_absent_release(object) \
321: MACRO_BEGIN \
322: (object)->absent_count--; \
323: vm_object_wakeup((object), \
324: VM_OBJECT_EVENT_ABSENT_COUNT); \
325: MACRO_END
326:
327: /*
328: * Object locking macros (with and without debugging)
329: */
330:
331: #if VM_OBJECT_DEBUG
332: #define vm_object_lock_init(object) \
333: MACRO_BEGIN \
334: simple_lock_init(&(object)->Lock); \
335: (object)->LockHolder = 0; \
336: MACRO_END
337: #define vm_object_lock(object) \
338: MACRO_BEGIN \
339: simple_lock(&(object)->Lock); \
340: (object)->LockHolder = current_thread(); \
341: MACRO_END
342: #define vm_object_unlock(object) \
343: MACRO_BEGIN \
344: if ((object)->LockHolder != current_thread()) \
345: panic("vm_object_unlock 0x%x", (object)); \
346: (object)->LockHolder = 0; \
347: simple_unlock(&(object)->Lock); \
348: MACRO_END
349: #define vm_object_lock_try(object) \
350: (simple_lock_try(&(object)->Lock) \
351: ? ( ((object)->LockHolder = current_thread()) , TRUE) \
352: : FALSE)
353: #define vm_object_sleep(event, object, interruptible) \
354: MACRO_BEGIN \
355: if ((object)->LockHolder != current_thread()) \
356: panic("vm_object_sleep %#x", (object)); \
357: (object)->LockHolder = 0; \
358: thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
359: (interruptible)); \
360: MACRO_END
361: #define vm_object_lock_taken(object) \
362: ((object)->LockHolder == current_thread())
363: #else /* VM_OBJECT_DEBUG */
364: #define vm_object_lock_init(object) simple_lock_init(&(object)->Lock)
365: #define vm_object_lock(object) simple_lock(&(object)->Lock)
366: #define vm_object_unlock(object) simple_unlock(&(object)->Lock)
367: #define vm_object_lock_try(object) simple_lock_try(&(object)->Lock)
368: #define vm_object_sleep(event, object, interruptible) \
369: thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
370: (interruptible))
371: #define vm_object_lock_taken(object) simple_lock_taken(&(object)->Lock)
372: #endif /* VM_OBJECT_DEBUG */
373:
374: #endif /* _VM_VM_OBJECT_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.