Annotation of OSKit-Mach/vm/vm_page.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1993-1988 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/vm_page.h
                     28:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     29:  *     Date:   1985
                     30:  *
                     31:  *     Resident memory system definitions.
                     32:  */
                     33: 
                     34: #ifndef        _VM_VM_PAGE_H_
                     35: #define _VM_VM_PAGE_H_
                     36: 
                     37: #include <mach_vm_debug.h>
                     38: 
                     39: #include <mach/boolean.h>
                     40: #include <mach/vm_prot.h>
                     41: #include <mach/vm_param.h>
                     42: #include <vm/vm_object.h>
                     43: #include <kern/queue.h>
                     44: #include <kern/lock.h>
                     45: #include <kern/zalloc.h>
                     46: 
                     47: #include <kern/macro_help.h>
                     48: #include <kern/sched_prim.h>   /* definitions of wait/wakeup */
                     49: 
                     50: #if    MACH_VM_DEBUG
                     51: #include <mach_debug/hash_info.h>
                     52: #endif
                     53: 
                     54: /*
                     55:  *     Management of resident (logical) pages.
                     56:  *
                     57:  *     A small structure is kept for each resident
                     58:  *     page, indexed by page number.  Each structure
                     59:  *     is an element of several lists:
                     60:  *
                     61:  *             A hash table bucket used to quickly
                     62:  *             perform object/offset lookups
                     63:  *
                     64:  *             A list of all pages for a given object,
                     65:  *             so they can be quickly deactivated at
                     66:  *             time of deallocation.
                     67:  *
                     68:  *             An ordered list of pages due for pageout.
                     69:  *
                     70:  *     In addition, the structure contains the object
                     71:  *     and offset to which this page belongs (for pageout),
                     72:  *     and sundry status bits.
                     73:  *
                     74:  *     Fields in this structure are locked either by the lock on the
                     75:  *     object that the page belongs to (O) or by the lock on the page
                     76:  *     queues (P).  [Some fields require that both locks be held to
                     77:  *     change that field; holding either lock is sufficient to read.]
                     78:  */
                     79: 
                     80: struct vm_page {
                     81:        queue_chain_t   pageq;          /* queue info for FIFO
                     82:                                         * queue or free list (P) */
                     83:        queue_chain_t   listq;          /* all pages in same object (O) */
                     84:        struct vm_page  *next;          /* VP bucket link (O) */
                     85: 
                     86:        vm_object_t     object;         /* which object am I in (O,P) */
                     87:        vm_offset_t     offset;         /* offset into that object (O,P) */
                     88: 
                     89:        unsigned int    wire_count:16,  /* how many wired down maps use me?
                     90:                                           (O&P) */
                     91:        /* boolean_t */ inactive:1,     /* page is in inactive list (P) */
                     92:                        active:1,       /* page is in active list (P) */
                     93:                        laundry:1,      /* page is being cleaned now (P)*/
                     94:                        free:1,         /* page is on free list (P) */
                     95:                        reference:1,    /* page has been used (P) */
                     96:                        external:1,     /* page considered external (P) */
                     97:                        extcounted:1,   /* page counted in ext counts (P) */
                     98:                        :0;             /* (force to 'long' boundary) */
                     99: #ifdef ns32000
                    100:        int             pad;            /* extra space for ns32000 bit ops */
                    101: #endif /* ns32000 */
                    102: 
                    103:        unsigned int
                    104:        /* boolean_t */ busy:1,         /* page is in transit (O) */
                    105:                        wanted:1,       /* someone is waiting for page (O) */
                    106:                        tabled:1,       /* page is in VP table (O) */
                    107:                        fictitious:1,   /* Physical page doesn't exist (O) */
                    108:                        private:1,      /* Page should not be returned to
                    109:                                         *  the free list (O) */
                    110:                        absent:1,       /* Data has been requested, but is
                    111:                                         *  not yet available (O) */
                    112:                        error:1,        /* Data manager was unable to provide
                    113:                                         *  data due to error (O) */
                    114:                        dirty:1,        /* Page must be cleaned (O) */
                    115:                        precious:1,     /* Page is precious; data must be
                    116:                                         *  returned even if clean (O) */
                    117:                        overwriting:1,  /* Request to unlock has been made
                    118:                                         * without having data. (O)
                    119:                                         * [See vm_object_overwrite] */
                    120:                        :0;
                    121: 
                    122:        vm_offset_t     phys_addr;      /* Physical address of page, passed
                    123:                                         *  to pmap_enter (read-only) */
                    124:        vm_prot_t       page_lock;      /* Uses prohibited by data manager (O) */
                    125:        vm_prot_t       unlock_request; /* Outstanding unlock request (O) */
                    126: };
                    127: 
                    128: typedef struct vm_page *vm_page_t;
                    129: 
                    130: #define VM_PAGE_NULL           ((vm_page_t) 0)
                    131: 
                    132: /*
                    133:  *     For debugging, this macro can be defined to perform
                    134:  *     some useful check on a page structure.
                    135:  */
                    136: 
                    137: #define VM_PAGE_CHECK(mem)
                    138: 
                    139: /*
                    140:  *     Each pageable resident page falls into one of three lists:
                    141:  *
                    142:  *     free
                    143:  *             Available for allocation now.
                    144:  *     inactive
                    145:  *             Not referenced in any map, but still has an
                    146:  *             object/offset-page mapping, and may be dirty.
                    147:  *             This is the list of pages that should be
                    148:  *             paged out next.
                    149:  *     active
                    150:  *             A list of pages which have been placed in
                    151:  *             at least one physical map.  This list is
                    152:  *             ordered, in LRU-like fashion.
                    153:  */
                    154: 
                    155: extern
                    156: vm_page_t      vm_page_queue_free;     /* memory free queue */
                    157: extern
                    158: vm_page_t      vm_page_queue_fictitious;       /* fictitious free queue */
                    159: extern
                    160: queue_head_t   vm_page_queue_active;   /* active memory queue */
                    161: extern
                    162: queue_head_t   vm_page_queue_inactive; /* inactive memory queue */
                    163: 
                    164: extern
                    165: vm_offset_t    first_phys_addr;        /* physical address for first_page */
                    166: extern
                    167: vm_offset_t    last_phys_addr;         /* physical address for last_page */
                    168: 
                    169: #define vm_page_free_count (vm_page_queue_free_count + vm_page_unqueued_count)
                    170: extern
                    171: int    vm_page_queue_free_count; /* How many are on vm_page_queue_free? */
                    172: extern
                    173: int    vm_page_unqueued_count; /* How many are in the LMM? */
                    174: extern
                    175: int    vm_page_fictitious_count;/* How many fictitious pages are free? */
                    176: extern
                    177: int    vm_page_active_count;   /* How many pages are active? */
                    178: extern
                    179: int    vm_page_inactive_count; /* How many pages are inactive? */
                    180: extern
                    181: int    vm_page_wire_count;     /* How many pages are wired? */
                    182: extern
                    183: int    vm_page_free_target;    /* How many do we want free? */
                    184: extern
                    185: int    vm_page_free_min;       /* When to wakeup pageout */
                    186: extern
                    187: int    vm_page_inactive_target;/* How many do we want inactive? */
                    188: extern
                    189: int    vm_page_free_reserved;  /* How many pages reserved to do pageout */
                    190: extern
                    191: int    vm_page_laundry_count;  /* How many pages being laundered? */
                    192: extern
                    193: int    vm_page_external_limit; /* Max number of pages for external objects  */
                    194: 
                    195: /* Only objects marked with the extcounted bit are included in this total.
                    196:    Pages which we scan for possible pageout, but which are not actually
                    197:    dirty, don't get considered against the external page limits any more
                    198:    in this way.  */
                    199: extern
                    200: int    vm_page_external_count; /* How many pages for external objects? */
                    201: 
                    202: 
                    203: 
                    204: decl_simple_lock_data(extern,vm_page_queue_lock)/* lock on active and inactive
                    205:                                                   page queues */
                    206: decl_simple_lock_data(extern,vm_page_queue_free_lock)
                    207:                                                /* lock on free page queue */
                    208: 
                    209: extern unsigned int    vm_page_free_wanted;
                    210:                                /* how many threads are waiting for memory */
                    211: 
                    212: extern vm_offset_t     vm_page_fictitious_addr;
                    213:                                /* (fake) phys_addr of fictitious pages */
                    214: 
                    215: extern void            vm_page_bootstrap(
                    216:        vm_offset_t     *startp,
                    217:        vm_offset_t     *endp);
                    218: extern void            vm_page_module_init(void);
                    219: 
                    220: extern void            vm_page_create(
                    221:        vm_offset_t     start,
                    222:        vm_offset_t     end);
                    223: extern vm_page_t       vm_page_lookup(
                    224:        vm_object_t     object,
                    225:        vm_offset_t     offset);
                    226: extern vm_page_t       vm_page_grab_fictitious(void);
                    227: extern void            vm_page_release_fictitious(vm_page_t);
                    228: extern boolean_t       vm_page_convert(vm_page_t, boolean_t);
                    229: extern void            vm_page_more_fictitious(void);
                    230: extern vm_page_t       vm_page_grab(boolean_t);
                    231: extern void            vm_page_release(vm_page_t, boolean_t);
                    232: extern void            vm_page_wait(void (*)(void));
                    233: extern vm_page_t       vm_page_alloc(
                    234:        vm_object_t     object,
                    235:        vm_offset_t     offset);
                    236: extern void            vm_page_init(
                    237:        vm_page_t       mem,
                    238:        vm_offset_t     phys_addr);
                    239: extern void            vm_page_free(vm_page_t);
                    240: extern void            vm_page_activate(vm_page_t);
                    241: extern void            vm_page_deactivate(vm_page_t);
                    242: extern void            vm_page_rename(
                    243:        vm_page_t       mem,
                    244:        vm_object_t     new_object,
                    245:        vm_offset_t     new_offset);
                    246: extern void            vm_page_insert(
                    247:        vm_page_t       mem,
                    248:        vm_object_t     object,
                    249:        vm_offset_t     offset);
                    250: extern void            vm_page_remove(
                    251:        vm_page_t       mem);
                    252: 
                    253: extern void            vm_page_zero_fill(vm_page_t);
                    254: extern void            vm_page_copy(vm_page_t src_m, vm_page_t dest_m);
                    255: 
                    256: extern void            vm_page_wire(vm_page_t);
                    257: extern void            vm_page_unwire(vm_page_t);
                    258: 
                    259: extern void            vm_set_page_size(void);
                    260: 
                    261: #if    MACH_VM_DEBUG
                    262: extern unsigned int    vm_page_info(
                    263:        hash_info_bucket_t      *info,
                    264:        unsigned int            count);
                    265: #endif
                    266: 
                    267: /*
                    268:  *     Functions implemented as macros
                    269:  */
                    270: 
                    271: #define PAGE_ASSERT_WAIT(m, interruptible)                     \
                    272:                MACRO_BEGIN                                     \
                    273:                (m)->wanted = TRUE;                             \
                    274:                assert_wait((event_t) (m), (interruptible));    \
                    275:                MACRO_END
                    276: 
                    277: #define PAGE_WAKEUP_DONE(m)                                    \
                    278:                MACRO_BEGIN                                     \
                    279:                (m)->busy = FALSE;                              \
                    280:                if ((m)->wanted) {                              \
                    281:                        (m)->wanted = FALSE;                    \
                    282:                        thread_wakeup(((event_t) m));           \
                    283:                }                                               \
                    284:                MACRO_END
                    285: 
                    286: #define PAGE_WAKEUP(m)                                         \
                    287:                MACRO_BEGIN                                     \
                    288:                if ((m)->wanted) {                              \
                    289:                        (m)->wanted = FALSE;                    \
                    290:                        thread_wakeup((event_t) (m));           \
                    291:                }                                               \
                    292:                MACRO_END
                    293: 
                    294: #define VM_PAGE_FREE(p)                        \
                    295:                MACRO_BEGIN                     \
                    296:                vm_page_lock_queues();          \
                    297:                vm_page_free(p);                \
                    298:                vm_page_unlock_queues();        \
                    299:                MACRO_END
                    300: 
                    301: /*
                    302:  *     Macro to be used in place of pmap_enter()
                    303:  */
                    304: 
                    305: #define PMAP_ENTER(pmap, virtual_address, page, protection, wired) \
                    306:                MACRO_BEGIN                                     \
                    307:                pmap_enter(                                     \
                    308:                        (pmap),                                 \
                    309:                        (virtual_address),                      \
                    310:                        (page)->phys_addr,                      \
                    311:                        (protection) & ~(page)->page_lock,      \
                    312:                        (wired)                                 \
                    313:                 );                                             \
                    314:                MACRO_END
                    315: 
                    316: #define        VM_PAGE_WAIT(continuation)      vm_page_wait(continuation)
                    317: 
                    318: #define vm_page_lock_queues()  simple_lock(&vm_page_queue_lock)
                    319: #define vm_page_unlock_queues()        simple_unlock(&vm_page_queue_lock)
                    320: 
                    321: #define VM_PAGE_QUEUES_REMOVE(mem)                             \
                    322:        MACRO_BEGIN                                             \
                    323:        if (mem->active) {                                      \
                    324:                queue_remove(&vm_page_queue_active,             \
                    325:                        mem, vm_page_t, pageq);                 \
                    326:                mem->active = FALSE;                            \
                    327:                vm_page_active_count--;                         \
                    328:        }                                                       \
                    329:                                                                \
                    330:        if (mem->inactive) {                                    \
                    331:                queue_remove(&vm_page_queue_inactive,           \
                    332:                        mem, vm_page_t, pageq);                 \
                    333:                mem->inactive = FALSE;                          \
                    334:                vm_page_inactive_count--;                       \
                    335:        }                                                       \
                    336:        MACRO_END
                    337: 
                    338: #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.