Annotation of kernel/vm/vm_page.h, revision 1.1.1.1

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_ */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.