|
|
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.