|
|
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-1988 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/vm_page.h ! 52: * Author: Avadis Tevanian, Jr., Michael Wayne Young ! 53: * Date: 1985 ! 54: * ! 55: * Resident memory system definitions. ! 56: */ ! 57: ! 58: #ifndef _VM_VM_PAGE_H_ ! 59: #define _VM_VM_PAGE_H_ ! 60: ! 61: #import <mach/features.h> ! 62: ! 63: #include <mach/boolean.h> ! 64: #include <mach/vm_prot.h> ! 65: #include <mach/vm_param.h> ! 66: #include <vm/vm_object.h> ! 67: #include <kern/queue.h> ! 68: #include <kern/lock.h> ! 69: #include <kern/zalloc.h> ! 70: ! 71: #include <kern/macro_help.h> ! 72: #include <kern/sched_prim.h> /* definitions of wait/wakeup */ ! 73: ! 74: #if MACH_VM_DEBUG ! 75: #include <mach_debug/hash_info.h> ! 76: #endif ! 77: ! 78: /* ! 79: * Management of resident (logical) pages. ! 80: * ! 81: * A small structure is kept for each resident ! 82: * page, indexed by page number. Each structure ! 83: * is an element of several lists: ! 84: * ! 85: * A hash table bucket used to quickly ! 86: * perform object/offset lookups ! 87: * ! 88: * A list of all pages for a given object, ! 89: * so they can be quickly deactivated at ! 90: * time of deallocation. ! 91: * ! 92: * An ordered list of pages due for pageout. ! 93: * ! 94: * In addition, the structure contains the object ! 95: * and offset to which this page belongs (for pageout), ! 96: * and sundry status bits. ! 97: * ! 98: * Fields in this structure are locked either by the lock on the ! 99: * object that the page belongs to (O) or by the lock on the page ! 100: * queues (P). [Some fields require that both locks be held to ! 101: * change that field; holding either lock is sufficient to read.] ! 102: */ ! 103: ! 104: struct vm_page { ! 105: queue_chain_t pageq; /* queue info for FIFO ! 106: * queue or free list (P) */ ! 107: queue_chain_t listq; /* all pages in same object (O) */ ! 108: struct vm_page *next; /* VP bucket link (O) */ ! 109: ! 110: vm_object_t object; /* which object am I in (O,P) */ ! 111: vm_offset_t offset; /* offset into that object (O,P) */ ! 112: ! 113: unsigned int wire_count:16, /* how many wired down maps use me? ! 114: (O&P) */ ! 115: /* boolean_t */ inactive:1, /* page is in inactive list (P) */ ! 116: active:1, /* page is in active list (P) */ ! 117: laundry:1, /* page is being cleaned now (P)*/ ! 118: free:1, /* page is on free list (P) */ ! 119: reference:1, /* page has been used (P) */ ! 120: #if OLD_VM_CODE ! 121: clean:1, /* page has not been modified (P) */ ! 122: #endif ! 123: :0; /* (force to 'long' boundary) */ ! 124: ! 125: unsigned int ! 126: /* boolean_t */ busy:1, /* page is in transit (O) */ ! 127: wanted:1, /* someone is waiting for page (O) */ ! 128: tabled:1, /* page is in VP table (O) */ ! 129: fictitious:1, /* Physical page doesn't exist (O) */ ! 130: private:1, /* Page should not be returned to ! 131: * the free list (O) */ ! 132: absent:1, /* Data has been requested, but is ! 133: * not yet available (O) */ ! 134: error:1, /* Data manager was unable to provide ! 135: * data due to error (O) */ ! 136: dirty:1, /* Page must be cleaned (O) */ ! 137: precious:1, /* Page is precious; data must be ! 138: * returned even if clean (O) */ ! 139: overwriting:1, /* Request to unlock has been made ! 140: * without having data. (O) ! 141: * [See vm_object_overwrite] */ ! 142: #if OLD_VM_CODE ! 143: copy_on_write:1,/* Page must be copied before being ! 144: * changed (O) */ ! 145: nfspagereq:1, /* NFS pagein request (O) */ ! 146: asyncrw:1, /* Async read/write */ ! 147: #endif ! 148: :0; ! 149: ! 150: vm_offset_t phys_addr; /* Physical address of page, passed ! 151: * to pmap_enter (read-only) */ ! 152: vm_prot_t page_lock; /* Uses prohibited by data manager (O) */ ! 153: vm_prot_t unlock_request; /* Outstanding unlock request (O) */ ! 154: }; ! 155: ! 156: typedef struct vm_page *vm_page_t; ! 157: ! 158: #define VM_PAGE_NULL ((vm_page_t) 0) ! 159: ! 160: /* ! 161: * For debugging, this macro can be defined to perform ! 162: * some useful check on a page structure. ! 163: */ ! 164: ! 165: #define VM_PAGE_CHECK(mem) ! 166: ! 167: /* ! 168: * Each pageable resident page falls into one of three lists: ! 169: * ! 170: * free ! 171: * Available for allocation now. ! 172: * inactive ! 173: * Not referenced in any map, but still has an ! 174: * object/offset-page mapping, and may be dirty. ! 175: * This is the list of pages that should be ! 176: * paged out next. ! 177: * active ! 178: * A list of pages which have been placed in ! 179: * at least one physical map. This list is ! 180: * ordered, in LRU-like fashion. ! 181: */ ! 182: ! 183: #if OLD_VM_CODE ! 184: extern ! 185: queue_head_t vm_page_queue_free; /* memory free queue */ ! 186: #else ! 187: extern ! 188: vm_page_t vm_page_queue_free; /* memory free queue */ ! 189: extern ! 190: vm_page_t vm_page_queue_fictitious; /* fictitious free queue */ ! 191: #endif ! 192: extern ! 193: queue_head_t vm_page_queue_active; /* active memory queue */ ! 194: extern ! 195: queue_head_t vm_page_queue_inactive; /* inactive memory queue */ ! 196: ! 197: extern ! 198: vm_offset_t first_phys_addr; /* physical address for first_page */ ! 199: extern ! 200: vm_offset_t last_phys_addr; /* physical address for last_page */ ! 201: ! 202: extern ! 203: int vm_page_free_count; /* How many pages are free? */ ! 204: extern ! 205: int vm_page_fictitious_count;/* How many fictitious pages are free? */ ! 206: extern ! 207: int vm_page_active_count; /* How many pages are active? */ ! 208: extern ! 209: int vm_page_inactive_count; /* How many pages are inactive? */ ! 210: extern ! 211: int vm_page_wire_count; /* How many pages are wired? */ ! 212: extern ! 213: int vm_page_free_target; /* How many do we want free? */ ! 214: extern ! 215: int vm_page_free_min; /* When to wakeup pageout */ ! 216: extern ! 217: int vm_page_inactive_target;/* How many do we want inactive? */ ! 218: extern ! 219: int vm_page_free_reserved; /* How many pages reserved to do pageout */ ! 220: extern ! 221: int vm_page_laundry_count; /* How many pages being laundered? */ ! 222: #if OLD_VM_CODE ! 223: extern ! 224: int vm_page_inactive_target_min;/* Inactive low water mark (floor) */ ! 225: ! 226: #define VM_PAGE_TO_PHYS(entry) ((entry)->phys_addr) ! 227: ! 228: #define IS_VM_PHYSADDR(pa) (vm_valid_page(pa)) ! 229: ! 230: #define PHYS_TO_VM_PAGE(pa) (vm_phys_to_vm_page(pa)) ! 231: #endif ! 232: ! 233: decl_simple_lock_data(extern,vm_page_queue_lock)/* lock on active and inactive ! 234: page queues */ ! 235: decl_simple_lock_data(extern,vm_page_queue_free_lock) ! 236: /* lock on free page queue */ ! 237: ! 238: #if OLD_VM_CODE ! 239: vm_offset_t vm_page_startup(); ! 240: vm_page_t vm_page_lookup(vm_object_t, vm_offset_t); ! 241: vm_page_t vm_page_alloc(vm_object_t, vm_offset_t); ! 242: void vm_page_init(vm_page_t, vm_object_t, vm_offset_t, vm_offset_t); ! 243: void vm_page_free(vm_page_t); ! 244: void vm_page_addfree(vm_page_t); ! 245: void vm_page_activate(vm_page_t); ! 246: void vm_page_deactivate(vm_page_t); ! 247: void vm_page_rename(vm_page_t, vm_object_t, vm_offset_t); ! 248: void vm_page_insert(vm_page_t, vm_object_t, vm_offset_t); ! 249: void vm_page_remove(vm_page_t); ! 250: ! 251: boolean_t vm_page_zero_fill(vm_page_t); ! 252: void vm_page_copy(vm_page_t, vm_page_t); ! 253: ! 254: void vm_page_wire(vm_page_t); ! 255: void vm_page_unwire(vm_page_t); ! 256: ! 257: void vm_set_page_size(); ! 258: #else ! 259: extern unsigned int vm_page_free_wanted; ! 260: /* how many threads are waiting for memory */ ! 261: ! 262: extern vm_offset_t vm_page_fictitious_addr; ! 263: /* (fake) phys_addr of fictitious pages */ ! 264: ! 265: extern void vm_page_bootstrap( ! 266: vm_offset_t *startp, ! 267: vm_offset_t *endp); ! 268: extern void vm_page_module_init(void); ! 269: ! 270: extern void vm_page_create( ! 271: vm_offset_t start, ! 272: vm_offset_t end); ! 273: extern vm_page_t vm_page_lookup( ! 274: vm_object_t object, ! 275: vm_offset_t offset); ! 276: extern vm_page_t vm_page_grab_fictitious(void); ! 277: extern void vm_page_release_fictitious(vm_page_t); ! 278: extern boolean_t vm_page_convert(vm_page_t); ! 279: extern void vm_page_more_fictitious(void); ! 280: extern vm_page_t vm_page_grab(void); ! 281: extern void vm_page_release(vm_page_t); ! 282: extern void vm_page_wait(void (*)(void)); ! 283: extern vm_page_t vm_page_alloc( ! 284: vm_object_t object, ! 285: vm_offset_t offset); ! 286: extern void vm_page_init( ! 287: vm_page_t mem, ! 288: vm_offset_t phys_addr); ! 289: extern void vm_page_free(vm_page_t); ! 290: extern void vm_page_activate(vm_page_t); ! 291: extern void vm_page_deactivate(vm_page_t); ! 292: extern void vm_page_rename( ! 293: vm_page_t mem, ! 294: vm_object_t new_object, ! 295: vm_offset_t new_offset); ! 296: extern void vm_page_insert( ! 297: vm_page_t mem, ! 298: vm_object_t object, ! 299: vm_offset_t offset); ! 300: extern void vm_page_remove( ! 301: vm_page_t mem); ! 302: ! 303: extern void vm_page_zero_fill(vm_page_t); ! 304: extern void vm_page_copy(vm_page_t src_m, vm_page_t dest_m); ! 305: ! 306: extern void vm_page_wire(vm_page_t); ! 307: extern void vm_page_unwire(vm_page_t); ! 308: ! 309: extern void vm_set_page_size(void); ! 310: ! 311: #if MACH_VM_DEBUG ! 312: extern unsigned int vm_page_info( ! 313: hash_info_bucket_t *info, ! 314: unsigned int count); ! 315: #endif ! 316: #endif ! 317: ! 318: /* ! 319: * Functions implemented as macros ! 320: */ ! 321: ! 322: #if OLD_VM_CODE ! 323: #import <kern/sched_prim.h> /* definitions of wait/wakeup */ ! 324: ! 325: #define PAGE_ASSERT_WAIT(m, interruptible) { \ ! 326: (m)->wanted = TRUE; \ ! 327: assert_wait((m), (interruptible)); \ ! 328: } ! 329: ! 330: #define PAGE_WAKEUP(m) { \ ! 331: (m)->busy = FALSE; \ ! 332: if ((m)->wanted) { \ ! 333: (m)->wanted = FALSE; \ ! 334: thread_wakeup((m)); \ ! 335: } \ ! 336: } ! 337: ! 338: #define VM_PAGE_FREE(p) { \ ! 339: vm_page_lock_queues(); \ ! 340: vm_page_free(p); \ ! 341: vm_page_unlock_queues(); \ ! 342: } ! 343: #else ! 344: #define PAGE_ASSERT_WAIT(m, interruptible) \ ! 345: MACRO_BEGIN \ ! 346: (m)->wanted = TRUE; \ ! 347: assert_wait((event_t) (m), (interruptible)); \ ! 348: MACRO_END ! 349: ! 350: #define PAGE_WAKEUP_DONE(m) \ ! 351: MACRO_BEGIN \ ! 352: (m)->busy = FALSE; \ ! 353: if ((m)->wanted) { \ ! 354: (m)->wanted = FALSE; \ ! 355: thread_wakeup(((event_t) m)); \ ! 356: } \ ! 357: MACRO_END ! 358: ! 359: #define PAGE_WAKEUP(m) \ ! 360: MACRO_BEGIN \ ! 361: if ((m)->wanted) { \ ! 362: (m)->wanted = FALSE; \ ! 363: thread_wakeup((event_t) (m)); \ ! 364: } \ ! 365: MACRO_END ! 366: ! 367: #define VM_PAGE_FREE(p) \ ! 368: MACRO_BEGIN \ ! 369: vm_page_lock_queues(); \ ! 370: vm_page_free(p); \ ! 371: vm_page_unlock_queues(); \ ! 372: MACRO_END ! 373: #endif ! 374: ! 375: /* ! 376: * Macro to be used in place of pmap_enter() ! 377: */ ! 378: ! 379: #define PMAP_ENTER(pmap, virtual_address, page, protection, wired) \ ! 380: MACRO_BEGIN \ ! 381: pmap_enter( \ ! 382: (pmap), \ ! 383: (virtual_address), \ ! 384: (page)->phys_addr, \ ! 385: (protection) & ~(page)->page_lock, \ ! 386: (wired) \ ! 387: ); \ ! 388: MACRO_END ! 389: ! 390: #define VM_PAGE_WAIT(continuation) vm_page_wait(continuation) ! 391: ! 392: #define vm_page_lock_queues() simple_lock(&vm_page_queue_lock) ! 393: #define vm_page_unlock_queues() simple_unlock(&vm_page_queue_lock) ! 394: ! 395: #define VM_PAGE_QUEUES_REMOVE(mem) \ ! 396: MACRO_BEGIN \ ! 397: if (mem->active) { \ ! 398: queue_remove(&vm_page_queue_active, \ ! 399: mem, vm_page_t, pageq); \ ! 400: mem->active = FALSE; \ ! 401: vm_page_active_count--; \ ! 402: } \ ! 403: \ ! 404: if (mem->inactive) { \ ! 405: queue_remove(&vm_page_queue_inactive, \ ! 406: mem, vm_page_t, pageq); \ ! 407: mem->inactive = FALSE; \ ! 408: vm_page_inactive_count--; \ ! 409: } \ ! 410: MACRO_END ! 411: ! 412: #if OLD_VM_CODE ! 413: vm_page_t vm_page_alloc_sequential(vm_object_t, vm_offset_t, boolean_t); ! 414: #define vm_page_alloc(object, offset) \ ! 415: vm_page_alloc_sequential(object,offset,TRUE) ! 416: boolean_t vm_page_completeio(); ! 417: #define vm_page_set_modified(m) { (m)->clean = FALSE; } ! 418: #endif ! 419: ! 420: #endif /* _VM_VM_PAGE_H_ */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.