Annotation of Gnu-Mach/vm/vm_object.h, revision 1.1.1.6

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: 
1.1.1.3   root       37: #include <sys/types.h>
1.1       root       38: #include <mach/kern_return.h>
                     39: #include <mach/boolean.h>
                     40: #include <mach/memory_object.h>
                     41: #include <mach/port.h>
                     42: #include <mach/vm_prot.h>
                     43: #include <mach/machine/vm_types.h>
                     44: #include <kern/queue.h>
                     45: #include <kern/lock.h>
                     46: #include <kern/assert.h>
1.1.1.3   root       47: #include <kern/debug.h>
1.1.1.5   root       48: #include <kern/macros.h>
1.1       root       49: #include <vm/pmap.h>
1.1.1.3   root       50: #include <ipc/ipc_types.h>
1.1       root       51: 
                     52: #if    MACH_PAGEMAP
                     53: #include <vm/vm_external.h>
                     54: #endif /* MACH_PAGEMAP */
                     55: 
                     56: typedef struct ipc_port *      pager_request_t;
                     57: #define        PAGER_REQUEST_NULL      ((pager_request_t) 0)
                     58: 
                     59: /*
                     60:  *     We use "struct ipc_port *" instead of "ipc_port_t"
                     61:  *     to avoid include file circularities.
                     62:  */
                     63: 
                     64: struct vm_object {
1.1.1.6 ! root       65:        queue_head_t            memq;           /* Resident memory */
1.1       root       66:        decl_simple_lock_data(, Lock)           /* Synchronization */
                     67: #if    VM_OBJECT_DEBUG
                     68:        thread_t                LockHolder;     /* Thread holding Lock */
1.1.1.2   root       69: #endif /* VM_OBJECT_DEBUG */
1.1       root       70:        vm_size_t               size;           /* Object size (only valid
                     71:                                                 * if internal)
                     72:                                                 */
                     73: 
1.1.1.3   root       74:        int                     ref_count;      /* Number of references */
1.1.1.6 ! root       75:        unsigned long           resident_page_count;
1.1       root       76:                                                /* number of resident pages */
                     77: 
                     78:        struct vm_object        *copy;          /* Object that should receive
                     79:                                                 * a copy of my changed pages
                     80:                                                 */
                     81:        struct vm_object        *shadow;        /* My shadow */
                     82:        vm_offset_t             shadow_offset;  /* Offset into shadow */
                     83: 
                     84:        struct ipc_port         *pager;         /* Where to get data */
                     85:        vm_offset_t             paging_offset;  /* Offset into memory object */
                     86:        pager_request_t         pager_request;  /* Where data comes back */
                     87:        struct ipc_port         *pager_name;    /* How to identify region */
                     88: 
                     89:        memory_object_copy_strategy_t
                     90:                                copy_strategy;  /* How to handle data copy */
                     91: 
                     92:        unsigned int
                     93:                                absent_count;   /* The number of pages that
                     94:                                                 * have been requested but
                     95:                                                 * not filled.  That is, the
                     96:                                                 * number of pages for which
                     97:                                                 * the "absent" attribute is
                     98:                                                 * asserted.
                     99:                                                 */
                    100: 
                    101:        unsigned int /* boolean_t array */
                    102:                                all_wanted;     /* Bit array of "want to be
                    103:                                                 * awakened" notations.  See
                    104:                                                 * VM_OBJECT_EVENT_* items
                    105:                                                 * below
                    106:                                                 */
                    107: 
                    108:        unsigned int
                    109:                                paging_in_progress:16,
                    110:                                                /* The memory object ports are
                    111:                                                 * being used (e.g., for pagein
                    112:                                                 * or pageout) -- don't change any
                    113:                                                 * of these fields (i.e., don't
                    114:                                                 * collapse, destroy or terminate)
                    115:                                                 */
1.1.1.6 ! root      116:        /* boolean_t */         used_for_pageout:1,/* The object carries data sent to
        !           117:                                                 * a memory manager, which signals
        !           118:                                                 * it's done by releasing memory.
        !           119:                                                 * This flag prevents coalescing so
        !           120:                                                 * that unmapping memory immediately
        !           121:                                                 * results in object termination.
        !           122:                                                 */
1.1       root      123:        /* boolean_t */         pager_created:1,/* Has pager ever been created? */
                    124:        /* boolean_t */         pager_initialized:1,/* Are fields ready to use? */
                    125:        /* boolean_t */         pager_ready:1,  /* Will manager take requests? */
                    126: 
                    127:        /* boolean_t */         can_persist:1,  /* The kernel may keep the data
                    128:                                                 * for this object (and rights to
                    129:                                                 * the memory object) after all
                    130:                                                 * address map references are
                    131:                                                 * deallocated?
                    132:                                                 */
                    133:        /* boolean_t */         internal:1,     /* Created by the kernel (and
                    134:                                                 * therefore, managed by the
                    135:                                                 * default memory manger)
                    136:                                                 */
                    137:        /* boolean_t */         temporary:1,    /* Permanent objects may be changed
                    138:                                                 * externally by the memory manager,
                    139:                                                 * and changes made in memory must
                    140:                                                 * be reflected back to the memory
                    141:                                                 * manager.  Temporary objects lack
                    142:                                                 * both of these characteristics.
                    143:                                                 */
                    144:        /* boolean_t */         alive:1,        /* Not yet terminated (debug) */
                    145:        /* boolean_t */         lock_in_progress : 1,
                    146:                                                /* Is a multi-page lock
                    147:                                                 * request in progress?
                    148:                                                 */
                    149:        /* boolean_t */         lock_restart : 1,
                    150:                                                /* Should lock request in
                    151:                                                 * progress restart search?
                    152:                                                 */
                    153:        /* boolean_t */         use_old_pageout : 1,
1.1.1.2   root      154:                                                /* Use old pageout primitives?
1.1       root      155:                                                 */
                    156:        /* boolean_t */         use_shared_copy : 1,/* Use shared (i.e.,
                    157:                                                 * delayed) copy on write */
1.1.1.6 ! root      158:        /* boolean_t */         shadowed: 1,    /* Shadow may exist */
1.1       root      159: 
1.1.1.6 ! root      160:        /* boolean_t */         cached: 1;      /* Object is cached */
1.1       root      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: extern
                    172: vm_object_t    kernel_object;          /* the single kernel object */
                    173: 
                    174: /*
                    175:  *     Declare procedures that operate on VM objects.
                    176:  */
                    177: 
                    178: extern void            vm_object_bootstrap(void);
                    179: extern void            vm_object_init(void);
1.1.1.6 ! root      180: extern void            vm_object_collect(vm_object_t);
1.1       root      181: extern void            vm_object_terminate(vm_object_t);
                    182: extern vm_object_t     vm_object_allocate(vm_size_t);
                    183: extern void            vm_object_reference(vm_object_t);
                    184: extern void            vm_object_deallocate(vm_object_t);
                    185: extern void            vm_object_pmap_protect(
                    186:        vm_object_t     object,
                    187:        vm_offset_t     offset,
                    188:        vm_size_t       size,
                    189:        pmap_t          pmap,
                    190:        vm_offset_t     pmap_start,
                    191:        vm_prot_t       prot);
                    192: extern void            vm_object_pmap_remove(
                    193:        vm_object_t     object,
                    194:        vm_offset_t     start,
                    195:        vm_offset_t     end);
                    196: extern void            vm_object_page_remove(
                    197:        vm_object_t     object,
                    198:        vm_offset_t     start,
                    199:        vm_offset_t     end);
                    200: extern void            vm_object_shadow(
                    201:        vm_object_t     *object,        /* in/out */
                    202:        vm_offset_t     *offset,        /* in/out */
                    203:        vm_size_t       length);
                    204: extern void            vm_object_collapse(vm_object_t);
                    205: extern vm_object_t     vm_object_lookup(struct ipc_port *);
                    206: extern vm_object_t     vm_object_lookup_name(struct ipc_port *);
                    207: extern struct ipc_port *vm_object_name(vm_object_t);
                    208: extern void            vm_object_remove(vm_object_t);
                    209: 
                    210: extern boolean_t       vm_object_copy_temporary(
                    211:        vm_object_t     *_object,               /* in/out */
                    212:        vm_offset_t     *_offset,               /* in/out */
                    213:        boolean_t       *_src_needs_copy,       /* out */
                    214:        boolean_t       *_dst_needs_copy);      /* out */
                    215: extern kern_return_t   vm_object_copy_strategically(
                    216:        vm_object_t     src_object,
                    217:        vm_offset_t     src_offset,
                    218:        vm_size_t       size,
                    219:        vm_object_t     *dst_object,            /* out */
                    220:        vm_offset_t     *dst_offset,            /* out */
                    221:        boolean_t       *dst_needs_copy);       /* out */
                    222: extern kern_return_t   vm_object_copy_slowly(
                    223:        vm_object_t     src_object,
                    224:        vm_offset_t     src_offset,
                    225:        vm_size_t       size,
                    226:        boolean_t       interruptible,
                    227:        vm_object_t     *_result_object);       /* out */
                    228: 
                    229: extern vm_object_t     vm_object_enter(
                    230:        struct ipc_port *pager,
                    231:        vm_size_t       size,
                    232:        boolean_t       internal);
                    233: extern void            vm_object_pager_create(
                    234:        vm_object_t     object);
                    235: extern void            vm_object_destroy(
                    236:        struct ipc_port *pager);
                    237: 
1.1.1.2   root      238: extern void vm_object_page_map(
                    239:        vm_object_t,
                    240:         vm_offset_t,
                    241:         vm_size_t,
1.1       root      242:        vm_offset_t     (*)(void *, vm_offset_t),
                    243:        void *);
                    244: 
                    245: extern vm_object_t     vm_object_request_object(struct ipc_port *);
                    246: 
1.1.1.3   root      247: extern boolean_t vm_object_coalesce(
                    248:    vm_object_t prev_object,
                    249:    vm_object_t next_object,
                    250:    vm_offset_t prev_offset,
                    251:    vm_offset_t next_offset,
                    252:    vm_size_t   prev_size,
                    253:    vm_size_t   next_size);
                    254: 
                    255: extern void vm_object_pager_wakeup(ipc_port_t  pager);
                    256: 
1.1.1.4   root      257: void memory_object_release(
                    258:        ipc_port_t      pager,
                    259:        pager_request_t pager_request,
                    260:        ipc_port_t      pager_name);
                    261: 
                    262: void vm_object_deactivate_pages(vm_object_t);
                    263: 
                    264: vm_object_t vm_object_copy_delayed(
                    265:        vm_object_t     src_object);
                    266: 
1.1       root      267: /*
                    268:  *     Event waiting handling
                    269:  */
                    270: 
                    271: #define        VM_OBJECT_EVENT_INITIALIZED             0
                    272: #define        VM_OBJECT_EVENT_PAGER_READY             1
                    273: #define        VM_OBJECT_EVENT_PAGING_IN_PROGRESS      2
                    274: #define        VM_OBJECT_EVENT_ABSENT_COUNT            3
                    275: #define        VM_OBJECT_EVENT_LOCK_IN_PROGRESS        4
                    276: 
                    277: #define        vm_object_wait(object, event, interruptible)                    \
                    278:        MACRO_BEGIN                                                     \
                    279:        (object)->all_wanted |= 1 << (event);                           \
                    280:        vm_object_sleep(((vm_offset_t) object) + (event),               \
                    281:                        (object),                                       \
                    282:                        (interruptible));                               \
                    283:        MACRO_END
                    284: 
                    285: #define        vm_object_assert_wait(object, event, interruptible)             \
                    286:        MACRO_BEGIN                                                     \
                    287:        (object)->all_wanted |= 1 << (event);                           \
                    288:        assert_wait((event_t)(((vm_offset_t) object) + (event)), (interruptible));      \
                    289:        MACRO_END
                    290: 
                    291: #define        vm_object_wakeup(object, event)                                 \
                    292:        MACRO_BEGIN                                                     \
                    293:        if ((object)->all_wanted & (1 << (event)))                      \
                    294:                thread_wakeup((event_t)(((vm_offset_t) object) + (event)));     \
                    295:        (object)->all_wanted &= ~(1 << (event));                        \
                    296:        MACRO_END
                    297: 
                    298: /*
                    299:  *     Routines implemented as macros
                    300:  */
                    301: 
1.1.1.6 ! root      302: #define vm_object_collectable(object)                                  \
        !           303:        (((object)->ref_count == 0)                                     \
        !           304:        && ((object)->resident_page_count == 0))
        !           305: 
1.1       root      306: #define        vm_object_paging_begin(object)                                  \
                    307:        ((object)->paging_in_progress++)
                    308: 
                    309: #define        vm_object_paging_end(object)                                    \
                    310:        MACRO_BEGIN                                                     \
                    311:        assert((object)->paging_in_progress != 0);                      \
                    312:        if (--(object)->paging_in_progress == 0) {                      \
                    313:                vm_object_wakeup(object,                                \
                    314:                        VM_OBJECT_EVENT_PAGING_IN_PROGRESS);            \
                    315:        }                                                               \
                    316:        MACRO_END
                    317: 
                    318: #define        vm_object_paging_wait(object, interruptible)                    \
                    319:        MACRO_BEGIN                                                     \
                    320:        while ((object)->paging_in_progress != 0) {                     \
                    321:                vm_object_wait( (object),                               \
                    322:                                VM_OBJECT_EVENT_PAGING_IN_PROGRESS,     \
                    323:                                (interruptible));                       \
                    324:                vm_object_lock(object);                                 \
                    325:                                                                        \
                    326:          /*XXX if ((interruptible) &&  */                              \
                    327:            /*XXX (current_thread()->wait_result != THREAD_AWAKENED))*/ \
                    328:                  /*XXX break; */                                       \
                    329:        }                                                               \
                    330:        MACRO_END
                    331: 
                    332: #define        vm_object_absent_assert_wait(object, interruptible)             \
                    333:        MACRO_BEGIN                                                     \
                    334:        vm_object_assert_wait(  (object),                               \
                    335:                        VM_OBJECT_EVENT_ABSENT_COUNT,                   \
                    336:                        (interruptible));                               \
                    337:        MACRO_END
                    338: 
                    339: 
                    340: #define        vm_object_absent_release(object)                                \
                    341:        MACRO_BEGIN                                                     \
                    342:        (object)->absent_count--;                                       \
                    343:        vm_object_wakeup((object),                                      \
                    344:                         VM_OBJECT_EVENT_ABSENT_COUNT);                 \
                    345:        MACRO_END
                    346: 
                    347: /*
                    348:  *     Object locking macros (with and without debugging)
                    349:  */
                    350: 
                    351: #if    VM_OBJECT_DEBUG
                    352: #define vm_object_lock_init(object) \
                    353: MACRO_BEGIN \
                    354:        simple_lock_init(&(object)->Lock); \
                    355:        (object)->LockHolder = 0; \
                    356: MACRO_END
                    357: #define vm_object_lock(object) \
                    358: MACRO_BEGIN \
                    359:        simple_lock(&(object)->Lock); \
                    360:        (object)->LockHolder = current_thread(); \
                    361: MACRO_END
                    362: #define vm_object_unlock(object) \
                    363: MACRO_BEGIN \
                    364:        if ((object)->LockHolder != current_thread()) \
                    365:            panic("vm_object_unlock 0x%x", (object)); \
                    366:        (object)->LockHolder = 0; \
                    367:        simple_unlock(&(object)->Lock); \
                    368: MACRO_END
                    369: #define vm_object_lock_try(object) \
                    370:        (simple_lock_try(&(object)->Lock) \
                    371:            ? ( ((object)->LockHolder = current_thread()) , TRUE) \
                    372:            : FALSE)
                    373: #define vm_object_sleep(event, object, interruptible) \
                    374: MACRO_BEGIN \
                    375:        if ((object)->LockHolder != current_thread()) \
                    376:            panic("vm_object_sleep %#x", (object)); \
                    377:        (object)->LockHolder = 0; \
                    378:        thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
                    379:                (interruptible)); \
                    380: MACRO_END
                    381: #define        vm_object_lock_taken(object)    \
                    382:                ((object)->LockHolder == current_thread())
                    383: #else  /* VM_OBJECT_DEBUG */
                    384: #define vm_object_lock_init(object)    simple_lock_init(&(object)->Lock)
                    385: #define vm_object_lock(object)         simple_lock(&(object)->Lock)
                    386: #define vm_object_unlock(object)       simple_unlock(&(object)->Lock)
                    387: #define vm_object_lock_try(object)     simple_lock_try(&(object)->Lock)
                    388: #define vm_object_sleep(event, object, interruptible)                  \
                    389:                thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
                    390:                             (interruptible))
                    391: #define        vm_object_lock_taken(object)    simple_lock_taken(&(object)->Lock)
                    392: #endif /* VM_OBJECT_DEBUG */
                    393: 
1.1.1.3   root      394: /*
                    395:  *     Page cache accounting.
                    396:  *
                    397:  *     The number of cached objects and pages can be read
                    398:  *     without holding any lock.
                    399:  */
                    400: 
                    401: extern int     vm_object_cached_count;
                    402: 
                    403: extern int     vm_object_cached_pages;
                    404: decl_simple_lock_data(extern,vm_object_cached_pages_lock_data)
                    405: 
                    406: #define vm_object_cached_pages_update(page_count)                      \
                    407:        MACRO_BEGIN                                                     \
                    408:        simple_lock(&vm_object_cached_pages_lock_data);                 \
                    409:        vm_object_cached_pages += (page_count);                         \
                    410:        simple_unlock(&vm_object_cached_pages_lock_data);               \
                    411:        MACRO_END
                    412: 
1.1       root      413: #endif /* _VM_VM_OBJECT_H_ */

unix.superglobalmegacorp.com

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