|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * Mach Operating System 3: * Copyright (c) 1993-1987 Carnegie Mellon University 4: * All Rights Reserved. 1.1.1.2 ! root 5: * 1.1 root 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. 1.1.1.2 ! root 11: * 1.1 root 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. 1.1.1.2 ! root 15: * 1.1 root 16: * Carnegie Mellon requests users of this software to return to 1.1.1.2 ! root 17: * 1.1 root 18: * Software Distribution Coordinator or [email protected] 19: * School of Computer Science 20: * Carnegie Mellon University 21: * Pittsburgh PA 15213-3890 1.1.1.2 ! root 22: * 1.1 root 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 */ 1.1.1.2 ! root 77: #endif /* VM_OBJECT_DEBUG */ 1.1 root 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, 1.1.1.2 ! root 155: /* Use old pageout primitives? 1.1 root 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: 1.1.1.2 ! root 240: extern void vm_object_page_map( ! 241: vm_object_t, ! 242: vm_offset_t, ! 243: vm_size_t, 1.1 root 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.