Annotation of XNU/osfmk/vm/vm_object.h, revision 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.