Annotation of XNU/osfmk/vm/vm_object.h, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * @OSF_COPYRIGHT@
                     24:  */
                     25: /* 
                     26:  * Mach Operating System
                     27:  * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
                     28:  * All Rights Reserved.
                     29:  * 
                     30:  * Permission to use, copy, modify and distribute this software and its
                     31:  * documentation is hereby granted, provided that both the copyright
                     32:  * notice and this permission notice appear in all copies of the
                     33:  * software, derivative works or modified versions, and any portions
                     34:  * thereof, and that both notices appear in supporting documentation.
                     35:  * 
                     36:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     37:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     38:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     39:  * 
                     40:  * Carnegie Mellon requests users of this software to return to
                     41:  * 
                     42:  *  Software Distribution Coordinator  or  [email protected]
                     43:  *  School of Computer Science
                     44:  *  Carnegie Mellon University
                     45:  *  Pittsburgh PA 15213-3890
                     46:  * 
                     47:  * any improvements or extensions that they make and grant Carnegie Mellon
                     48:  * the rights to redistribute these changes.
                     49:  */
                     50: /*
                     51:  */
                     52: /*
                     53:  *     File:   vm_object.h
                     54:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
                     55:  *     Date:   1985
                     56:  *
                     57:  *     Virtual memory object module definitions.
                     58:  */
                     59: 
                     60: #ifndef        _VM_VM_OBJECT_H_
                     61: #define _VM_VM_OBJECT_H_
                     62: 
                     63: #include <mach_pagemap.h>
                     64: #include <task_swapper.h>
                     65: 
                     66: #include <mach/kern_return.h>
                     67: #include <mach/boolean.h>
                     68: #include <mach/memory_object_types.h>
                     69: #include <mach/port.h>
                     70: #include <mach/vm_prot.h>
                     71: #include <mach/machine/vm_types.h>
                     72: #include <kern/queue.h>
                     73: #include <kern/lock.h>
                     74: #include <kern/assert.h>
                     75: #include <kern/macro_help.h>
                     76: #include <ipc/ipc_types.h>
                     77: #include <vm/pmap.h>
                     78: #include <kern/misc_protos.h>
                     79: 
                     80: #if    MACH_PAGEMAP
                     81: #include <vm/vm_external.h>
                     82: #endif /* MACH_PAGEMAP */
                     83: 
                     84: typedef struct ipc_port *      pager_request_t;
                     85: #define        PAGER_REQUEST_NULL      ((pager_request_t) 0)
                     86: 
                     87: /*
                     88:  *     Types defined:
                     89:  *
                     90:  *     vm_object_t             Virtual memory object.
                     91:  *
                     92:  *     We use "struct ipc_port *" instead of "ipc_port_t"
                     93:  *     to avoid include file circularities.
                     94:  */
                     95: 
                     96: struct vm_object {
                     97:        queue_head_t            memq;           /* Resident memory */
                     98:        decl_mutex_data(,       Lock)           /* Synchronization */
                     99: 
                    100:        vm_size_t               size;           /* Object size (only valid
                    101:                                                 * if internal)
                    102:                                                 */
                    103:        vm_size_t               frozen_size;    /* How much has been marked
                    104:                                                 * copy-on-write (only
                    105:                                                 * valid if copy_symmetric)
                    106:                                                 */
                    107:        int                     ref_count;      /* Number of references */
                    108: #if    TASK_SWAPPER
                    109:        int                     res_count;      /* Residency references (swap)*/
                    110: #endif /* TASK_SWAPPER */
                    111:        unsigned int            resident_page_count;
                    112:                                                /* number of resident pages */
                    113: 
                    114:        struct vm_object        *copy;          /* Object that should receive
                    115:                                                 * a copy of my changed pages,
                    116:                                                 * for copy_delay, or just the
                    117:                                                 * temporary object that
                    118:                                                 * shadows this object, for
                    119:                                                 * copy_call.
                    120:                                                 */
                    121:        struct vm_object        *shadow;        /* My shadow */
                    122:        vm_offset_t             shadow_offset;  /* Offset into shadow */
                    123: 
                    124:        struct ipc_port         *pager;         /* Where to get data */
                    125:        vm_offset_t             paging_offset;  /* Offset into memory object */
                    126:        pager_request_t         pager_request;  /* Where data comes back */
                    127: 
                    128:        memory_object_copy_strategy_t
                    129:                                copy_strategy;  /* How to handle data copy */
                    130: 
                    131:        unsigned int            absent_count;   /* The number of pages that
                    132:                                                 * have been requested but
                    133:                                                 * not filled.  That is, the
                    134:                                                 * number of pages for which
                    135:                                                 * the "absent" attribute is
                    136:                                                 * asserted.
                    137:                                                 */
                    138: 
                    139:        unsigned int            paging_in_progress;
                    140:                                                /* The memory object ports are
                    141:                                                 * being used (e.g., for pagein
                    142:                                                 * or pageout) -- don't change
                    143:                                                 * any of these fields (i.e.,
                    144:                                                 * don't collapse, destroy or
                    145:                                                 * terminate)
                    146:                                                 */
                    147:        unsigned int
                    148:        /* boolean_t array */   all_wanted:11,  /* Bit array of "want to be
                    149:                                                 * awakened" notations.  See
                    150:                                                 * VM_OBJECT_EVENT_* items
                    151:                                                 * below */
                    152:        /* boolean_t */ pager_created:1,        /* Has pager been created? */
                    153:        /* boolean_t */ pager_initialized:1,    /* Are fields ready to use? */
                    154:        /* boolean_t */ pager_ready:1,          /* Will pager take requests? */
                    155: 
                    156:        /* boolean_t */         pager_trusted:1,/* The pager for this object
                    157:                                                 * is trusted. This is true for
                    158:                                                 * all internal objects (backed
                    159:                                                 * by the default pager)
                    160:                                                 */
                    161:        /* boolean_t */         can_persist:1,  /* The kernel may keep the data
                    162:                                                 * for this object (and rights
                    163:                                                 * to the memory object) after
                    164:                                                 * all address map references 
                    165:                                                 * are deallocated?
                    166:                                                 */
                    167:        /* boolean_t */         internal:1,     /* Created by the kernel (and
                    168:                                                 * therefore, managed by the
                    169:                                                 * default memory manger)
                    170:                                                 */
                    171:        /* boolean_t */         temporary:1,    /* Permanent objects may be
                    172:                                                 * changed externally by the 
                    173:                                                 * memory manager, and changes
                    174:                                                 * made in memory must be
                    175:                                                 * reflected back to the memory
                    176:                                                 * manager.  Temporary objects
                    177:                                                 * lack both of these
                    178:                                                 * characteristics.
                    179:                                                 */
                    180:        /* boolean_t */         private:1,      /* magic device_pager object,
                    181:                                                 * holds private pages only */
                    182:        /* boolean_t */         pageout:1,      /* pageout object. contains
                    183:                                                 * private pages that refer to
                    184:                                                 * a real memory object. */
                    185:        /* boolean_t */         alive:1,        /* Not yet terminated */
                    186: 
                    187:        /* boolean_t */         lock_in_progress:1,
                    188:                                                /* Is a multi-page lock
                    189:                                                 * request in progress?
                    190:                                                 */
                    191:        /* boolean_t */         lock_restart:1,
                    192:                                                /* Should lock request in
                    193:                                                 * progress restart search?
                    194:                                                 */
                    195:        /* boolean_t */         shadowed:1,     /* Shadow may exist */
                    196:        /* boolean_t */         silent_overwrite:1,
                    197:                                                /* Allow full page overwrite
                    198:                                                 * without data_request if
                    199:                                                 * page is absent */
                    200:        /* boolean_t */         advisory_pageout:1,
                    201:                                                /* Instead of sending page
                    202:                                                 * via OOL, just notify
                    203:                                                 * pager that the kernel
                    204:                                                 * wants to discard it, page
                    205:                                                 * remains in object */
                    206:        /* boolean_t */         true_share:1;
                    207:                                                /* This object is mapped
                    208:                                                 * in more than one place
                    209:                                                 * and hence cannot be 
                    210:                                                 * coalesced */
                    211: 
                    212: 
                    213:        queue_chain_t           cached_list;    /* Attachment point for the
                    214:                                                 * list of objects cached as a
                    215:                                                 * result of their can_persist
                    216:                                                 * value
                    217:                                                 */
                    218: 
                    219:        queue_head_t            msr_q;          /* memory object synchronise
                    220:                                                   request queue */
                    221: 
                    222:        vm_offset_t             last_alloc;     /* last allocation offset */
                    223:        vm_size_t               cluster_size;   /* size of paging cluster */
                    224: #if    MACH_PAGEMAP
                    225:        vm_external_map_t       existence_map;  /* bitmap of pages written to
                    226:                                                 * backing storage */
                    227: #endif /* MACH_PAGEMAP */
                    228: #if    MACH_ASSERT
                    229:        struct vm_object        *paging_object; /* object which pages to be
                    230:                                                 * swapped out are temporary
                    231:                                                 * put in current object
                    232:                                                 */
                    233: #endif
                    234: };
                    235: 
                    236: extern
                    237: vm_object_t    kernel_object;          /* the single kernel object */
                    238: 
                    239: int            vm_object_absent_max;   /* maximum number of absent pages
                    240:                                           at a time for each object */
                    241: 
                    242: # define       VM_MSYNC_INITIALIZED                    0
                    243: # define       VM_MSYNC_SYNCHRONIZING                  1
                    244: # define       VM_MSYNC_DONE                           2
                    245: 
                    246: struct msync_req {
                    247:        queue_chain_t           msr_q;          /* object request queue */
                    248:        queue_chain_t           req_q;          /* vm_msync request queue */
                    249:        unsigned int            flag;
                    250:        vm_offset_t             offset;
                    251:        vm_offset_t             length;
                    252:        vm_object_t             object;         /* back pointer */
                    253:        decl_mutex_data(,       msync_req_lock) /* Lock for this structure */
                    254: };
                    255: 
                    256: typedef struct msync_req       *msync_req_t;
                    257: #define MSYNC_REQ_NULL         ((msync_req_t) 0)
                    258: 
                    259: /*
                    260:  * Macros to allocate and free msync_reqs
                    261:  */
                    262: #define msync_req_alloc(msr)                                           \
                    263:        MACRO_BEGIN                                                     \
                    264:         (msr) = (msync_req_t)kalloc(sizeof(struct msync_req));         \
                    265:         mutex_init(&(msr)->msync_req_lock, ETAP_VM_MSYNC);             \
                    266:        msr->flag = VM_MSYNC_INITIALIZED;                               \
                    267:         MACRO_END
                    268: 
                    269: #define msync_req_free(msr)                                            \
                    270:        (kfree((vm_offset_t)(msr), sizeof(struct msync_req)))
                    271: 
                    272: #define msr_lock(msr)   mutex_lock(&(msr)->msync_req_lock)
                    273: #define msr_unlock(msr) mutex_unlock(&(msr)->msync_req_lock)
                    274: 
                    275: /*
                    276:  *     Declare procedures that operate on VM objects.
                    277:  */
                    278: 
                    279: extern void            vm_object_bootstrap(void);
                    280: 
                    281: extern void            vm_object_init(void);
                    282: 
                    283: extern vm_object_t     vm_object_allocate(
                    284:                                        vm_size_t       size);
                    285: 
                    286: #if    MACH_ASSERT
                    287: extern void            vm_object_reference(
                    288:                                        vm_object_t     object);
                    289: #else  /* MACH_ASSERT */
                    290: #define        vm_object_reference(object)                     \
                    291: MACRO_BEGIN                                            \
                    292:        vm_object_t Object = (object);                  \
                    293:        if (Object) {                                   \
                    294:                vm_object_lock(Object);                 \
                    295:                Object->ref_count++;                    \
                    296:                vm_object_res_reference(Object);        \
                    297:                vm_object_unlock(Object);               \
                    298:        }                                               \
                    299: MACRO_END
                    300: #endif /* MACH_ASSERT */
                    301: 
                    302: extern void            vm_object_deallocate(
                    303:                                        vm_object_t     object);
                    304: 
                    305: extern void            vm_object_pmap_protect(
                    306:                                        vm_object_t     object,
                    307:                                        vm_offset_t     offset,
                    308:                                        vm_offset_t     size,
                    309:                                        pmap_t          pmap,
                    310:                                        vm_offset_t     pmap_start,
                    311:                                        vm_prot_t       prot);
                    312: 
                    313: extern void            vm_object_page_remove(
                    314:                                        vm_object_t     object,
                    315:                                        vm_offset_t     start,
                    316:                                        vm_offset_t     end);
                    317: 
                    318: extern boolean_t       vm_object_coalesce(
                    319:                                        vm_object_t     prev_object,
                    320:                                        vm_object_t     next_object,
                    321:                                        vm_offset_t     prev_offset,
                    322:                                        vm_offset_t     next_offset,
                    323:                                        vm_size_t       prev_size,
                    324:                                        vm_size_t       next_size);
                    325: 
                    326: extern boolean_t       vm_object_shadow(
                    327:                                        vm_object_t     *object,
                    328:                                        vm_offset_t     *offset,
                    329:                                        vm_size_t       length);
                    330: 
                    331: extern void            vm_object_collapse(
                    332:                                        vm_object_t     object);
                    333: 
                    334: extern vm_object_t     vm_object_lookup(
                    335:                                        ipc_port_t      port);
                    336: 
                    337: extern ipc_port_t      vm_object_name(
                    338:                                        vm_object_t     object);
                    339: 
                    340: extern boolean_t       vm_object_copy_quickly(
                    341:                                        vm_object_t     *_object,
                    342:                                        vm_offset_t     src_offset,
                    343:                                        vm_size_t       size,
                    344:                                        boolean_t       *_src_needs_copy,
                    345:                                        boolean_t       *_dst_needs_copy);
                    346: 
                    347: extern kern_return_t   vm_object_copy_strategically(
                    348:                                        vm_object_t     src_object,
                    349:                                        vm_offset_t     src_offset,
                    350:                                        vm_size_t       size,
                    351:                                        vm_object_t     *dst_object,
                    352:                                        vm_offset_t     *dst_offset,
                    353:                                        boolean_t       *dst_needs_copy);
                    354: 
                    355: extern kern_return_t   vm_object_copy_slowly(
                    356:                                        vm_object_t     src_object,
                    357:                                        vm_offset_t     src_offset,
                    358:                                        vm_size_t       size,
                    359:                                        boolean_t       interruptible,
                    360:                                        vm_object_t     *_result_object);
                    361: 
                    362: extern void            vm_object_pager_create(
                    363:                                        vm_object_t     object);
                    364: 
                    365: extern void            vm_object_destroy(
                    366:                                        ipc_port_t      pager);
                    367: 
                    368: extern void            vm_object_pager_wakeup(
                    369:                                        ipc_port_t      pager);
                    370: 
                    371: extern void            vm_object_page_map(
                    372:                                        vm_object_t     object,
                    373:                                        vm_offset_t     offset,
                    374:                                        vm_size_t       size,
                    375:                                        vm_offset_t     (*map_fn)
                    376:                                                (void *, vm_offset_t),
                    377:                                        void            *map_fn_data);
                    378: 
                    379: #if    TASK_SWAPPER
                    380: 
                    381: extern void            vm_object_res_reference(
                    382:                                        vm_object_t object);
                    383: extern void            vm_object_res_deallocate(
                    384:                                        vm_object_t object);
                    385: #define        VM_OBJ_RES_INCR(object) (object)->res_count++
                    386: #define        VM_OBJ_RES_DECR(object) (object)->res_count--
                    387: 
                    388: #else  /* TASK_SWAPPER */
                    389: 
                    390: #define        VM_OBJ_RES_INCR(object)
                    391: #define        VM_OBJ_RES_DECR(object)
                    392: #define vm_object_res_reference(object)
                    393: #define vm_object_res_deallocate(object)
                    394: 
                    395: #endif /* TASK_SWAPPER */
                    396: 
                    397: extern vm_object_t     vm_object_enter(
                    398:                                        ipc_port_t      pager,
                    399:                                        vm_size_t       size,
                    400:                                        boolean_t       internal,
                    401:                                        boolean_t       init);
                    402: 
                    403: 
                    404: extern vm_object_t     vm_object_copy_delayed(
                    405:                                vm_object_t     src_object,
                    406:                                vm_offset_t     src_offset,
                    407:                                vm_size_t       size);
                    408: 
                    409: 
                    410: /*
                    411:  *     Event waiting handling
                    412:  */
                    413: 
                    414: #define        VM_OBJECT_EVENT_INITIALIZED             0
                    415: #define        VM_OBJECT_EVENT_PAGER_READY             1
                    416: #define        VM_OBJECT_EVENT_PAGING_IN_PROGRESS      2
                    417: #define        VM_OBJECT_EVENT_ABSENT_COUNT            3
                    418: #define        VM_OBJECT_EVENT_LOCK_IN_PROGRESS        4
                    419: #define        VM_OBJECT_EVENT_UNCACHING               5
                    420: #define        VM_OBJECT_EVENT_COPY_CALL               6
                    421: #define        VM_OBJECT_EVENT_CACHING                 7
                    422: 
                    423: #define        vm_object_assert_wait(object, event, interruptible)             \
                    424:        MACRO_BEGIN                                                     \
                    425:        (object)->all_wanted |= 1 << (event);                           \
                    426:        assert_wait((event_t)((vm_offset_t)(object)+(event)),(interruptible)); \
                    427:        MACRO_END
                    428: 
                    429: #define        vm_object_wait(object, event, interruptible)                    \
                    430:        MACRO_BEGIN                                                     \
                    431:        vm_object_assert_wait((object),(event),(interruptible));        \
                    432:        vm_object_unlock(object);                                       \
                    433:        thread_block((void (*)(void)) 0);                               \
                    434:        MACRO_END
                    435: 
                    436: #define        vm_object_wakeup(object, event)                                 \
                    437:        MACRO_BEGIN                                                     \
                    438:        if ((object)->all_wanted & (1 << (event)))                      \
                    439:                thread_wakeup((event_t)((vm_offset_t)(object) + (event))); \
                    440:        (object)->all_wanted &= ~(1 << (event));                        \
                    441:        MACRO_END
                    442: 
                    443: #define        vm_object_set_wanted(object, event)                             \
                    444:        MACRO_BEGIN                                                     \
                    445:        ((object)->all_wanted |= (1 << (event)));                       \
                    446:        MACRO_END
                    447: 
                    448: #define        vm_object_wanted(object, event)                                 \
                    449:        ((object)->all_wanted & (1 << (event)))
                    450: 
                    451: /*
                    452:  *     Routines implemented as macros
                    453:  */
                    454: 
                    455: #define                vm_object_paging_begin(object)                          \
                    456:        MACRO_BEGIN                                                     \
                    457:        (object)->paging_in_progress++;                                 \
                    458:        MACRO_END
                    459: 
                    460: #define                vm_object_paging_end(object)                            \
                    461:        MACRO_BEGIN                                                     \
                    462:        assert((object)->paging_in_progress != 0);                      \
                    463:        if (--(object)->paging_in_progress == 0) {                      \
                    464:                vm_object_wakeup(object,                                \
                    465:                        VM_OBJECT_EVENT_PAGING_IN_PROGRESS);            \
                    466:        }                                                               \
                    467:        MACRO_END
                    468: 
                    469: #define                vm_object_paging_wait(object, interruptible)            \
                    470:        MACRO_BEGIN                                                     \
                    471:        while ((object)->paging_in_progress != 0) {                     \
                    472:                vm_object_wait( (object),                               \
                    473:                                VM_OBJECT_EVENT_PAGING_IN_PROGRESS,     \
                    474:                                (interruptible));                       \
                    475:                vm_object_lock(object);                                 \
                    476:                                                                        \
                    477:                /*XXX if ((interruptible) &&    */                      \
                    478:                    /*XXX (current_thread()->wait_result != THREAD_AWAKENED))*/ \
                    479:                        /*XXX break; */                                 \
                    480:        }                                                               \
                    481:        MACRO_END
                    482: 
                    483: #define        vm_object_absent_assert_wait(object, interruptible)             \
                    484:        MACRO_BEGIN                                                     \
                    485:        vm_object_assert_wait(  (object),                               \
                    486:                        VM_OBJECT_EVENT_ABSENT_COUNT,                   \
                    487:                        (interruptible));                               \
                    488:        MACRO_END
                    489: 
                    490: 
                    491: #define        vm_object_absent_release(object)                                \
                    492:        MACRO_BEGIN                                                     \
                    493:        (object)->absent_count--;                                       \
                    494:        vm_object_wakeup((object),                                      \
                    495:                         VM_OBJECT_EVENT_ABSENT_COUNT);                 \
                    496:        MACRO_END
                    497: 
                    498: /*
                    499:  *     Object locking macros
                    500:  */
                    501: 
                    502: #define vm_object_lock_init(object)    mutex_init(&(object)->Lock, ETAP_VM_OBJ)
                    503: #define vm_object_lock(object)         mutex_lock(&(object)->Lock)
                    504: #define vm_object_unlock(object)       mutex_unlock(&(object)->Lock)
                    505: #define vm_object_lock_try(object)     mutex_try(&(object)->Lock)
                    506: 
                    507: #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.