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