Annotation of kernel/vm/vm_object.h, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: 
        !            25: /* 
        !            26:  * Mach Operating System
        !            27:  * Copyright (c) 1993-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:  *     File:   vm_object.h
        !            52:  *     Author: Avadis Tevanian, Jr., Michael Wayne Young
        !            53:  *     Date:   1985
        !            54:  *
        !            55:  *     Virtual memory object module definitions.
        !            56:  */
        !            57: 
        !            58: #ifndef        _VM_VM_OBJECT_H_
        !            59: #define _VM_VM_OBJECT_H_
        !            60: 
        !            61: #import <mach/features.h>
        !            62: 
        !            63: #include <mach/kern_return.h>
        !            64: #include <mach/boolean.h>
        !            65: #include <mach/memory_object.h>
        !            66: #include <mach/port.h>
        !            67: #include <mach/vm_prot.h>
        !            68: #include <mach/machine/vm_types.h>
        !            69: #include <kern/queue.h>
        !            70: #include <kern/lock.h>
        !            71: #include <kern/assert.h>
        !            72: #include <kern/macro_help.h>
        !            73: #include <vm/pmap.h>
        !            74: #if    OLD_VM_CODE
        !            75: #import <vm/vm_pager.h>
        !            76: #endif
        !            77: 
        !            78: #if    MACH_PAGEMAP
        !            79: #include <vm/vm_external.h>
        !            80: #endif /* MACH_PAGEMAP */
        !            81: 
        !            82: #if    NORMA_VM
        !            83: typedef struct xmm_obj *       pager_request_t;
        !            84: #else  /* NORMA_VM */
        !            85: #if    OLD_VM_CODE
        !            86: typedef port_t                 pager_request_t;
        !            87: #else
        !            88: typedef struct ipc_port *      pager_request_t;
        !            89: #endif
        !            90: #endif /* NORMA_VM */
        !            91: #define        PAGER_REQUEST_NULL      ((pager_request_t) 0)
        !            92: 
        !            93: /*
        !            94:  *     Types defined:
        !            95:  *
        !            96:  *     vm_object_t             Virtual memory object.
        !            97:  *
        !            98:  *     We use "struct ipc_port *" instead of "ipc_port_t"
        !            99:  *     to avoid include file circularities.
        !           100:  */
        !           101: 
        !           102: struct vm_object {
        !           103:        queue_chain_t           memq;           /* Resident memory */
        !           104: #if    OLD_VM_CODE
        !           105:        queue_chain_t           object_list;    /* list of all objects */
        !           106: #endif
        !           107:        decl_simple_lock_data(, Lock)           /* Synchronization */
        !           108: #if    VM_OBJECT_DEBUG
        !           109:        thread_t                LockHolder;     /* Thread holding Lock */
        !           110: #endif /* VM_OBJECT_DEBUG */
        !           111:        vm_size_t               size;           /* Object size (only valid
        !           112:                                                 * if internal)
        !           113:                                                 */
        !           114: 
        !           115:        int                     ref_count;      /* Number of references */
        !           116:        int                     resident_page_count;
        !           117:                                                /* number of resident pages */
        !           118: 
        !           119:        struct vm_object        *copy;          /* Object that should receive
        !           120:                                                 * a copy of my changed pages
        !           121:                                                 */
        !           122:        struct vm_object        *shadow;        /* My shadow */
        !           123:        vm_offset_t             shadow_offset;  /* Offset into shadow */
        !           124: 
        !           125: #if    OLD_VM_CODE
        !           126:        vm_pager_t              pager;          /* Where to get data */
        !           127: #else
        !           128:        struct ipc_port         *pager;         /* Where to get data */
        !           129: #endif
        !           130:        vm_offset_t             paging_offset;  /* Offset into memory object */
        !           131:        pager_request_t         pager_request;  /* Where data comes back */
        !           132: #if    OLD_VM_CODE
        !           133:        vm_pager_t              pager_name;     /* How to identify region */
        !           134: #else
        !           135:        struct ipc_port         *pager_name;    /* How to identify region */
        !           136: #endif
        !           137: 
        !           138:        memory_object_copy_strategy_t
        !           139:                                copy_strategy;  /* How to handle data copy */
        !           140: 
        !           141:        unsigned int
        !           142:                                absent_count;   /* The number of pages that
        !           143:                                                 * have been requested but
        !           144:                                                 * not filled.  That is, the
        !           145:                                                 * number of pages for which
        !           146:                                                 * the "absent" attribute is
        !           147:                                                 * asserted.
        !           148:                                                 */
        !           149: 
        !           150:        unsigned int /* boolean_t array */
        !           151:                                all_wanted;     /* Bit array of "want to be
        !           152:                                                 * awakened" notations.  See
        !           153:                                                 * VM_OBJECT_EVENT_* items
        !           154:                                                 * below
        !           155:                                                 */
        !           156: 
        !           157:        unsigned int
        !           158:                                paging_in_progress:16,
        !           159:                                                /* The memory object ports are
        !           160:                                                 * being used (e.g., for pagein
        !           161:                                                 * or pageout) -- don't change any
        !           162:                                                 * of these fields (i.e., don't
        !           163:                                                 * collapse, destroy or terminate)
        !           164:                                                 */
        !           165:        /* boolean_t */         pager_created:1,/* Has pager ever been created? */
        !           166:        /* boolean_t */         pager_initialized:1,/* Are fields ready to use? */
        !           167:        /* boolean_t */         pager_ready:1,  /* Will manager take requests? */
        !           168: 
        !           169:        /* boolean_t */         can_persist:1,  /* The kernel may keep the data
        !           170:                                                 * for this object (and rights to
        !           171:                                                 * the memory object) after all
        !           172:                                                 * address map references are
        !           173:                                                 * deallocated?
        !           174:                                                 */
        !           175:        /* boolean_t */         internal:1,     /* Created by the kernel (and
        !           176:                                                 * therefore, managed by the
        !           177:                                                 * default memory manger)
        !           178:                                                 */
        !           179:        /* boolean_t */         temporary:1,    /* Permanent objects may be changed
        !           180:                                                 * externally by the memory manager,
        !           181:                                                 * and changes made in memory must
        !           182:                                                 * be reflected back to the memory
        !           183:                                                 * manager.  Temporary objects lack
        !           184:                                                 * both of these characteristics.
        !           185:                                                 */
        !           186:        /* boolean_t */         alive:1,        /* Not yet terminated (debug) */
        !           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 */         use_old_pageout : 1,
        !           196:                                                /* Use old pageout primitives? 
        !           197:                                                 */
        !           198:        /* boolean_t */         use_shared_copy : 1,/* Use shared (i.e.,
        !           199:                                                 * delayed) copy on write */
        !           200:        /* boolean_t */         shadowed: 1;    /* Shadow may exist */
        !           201: #if    OLD_VM_CODE
        !           202:        unsigned int
        !           203:                                policy:16,         /* Paging policy for obj */
        !           204:        /* boolean_t */         pager_creating :1, /* Pager being created? */
        !           205:        /* boolean_t */         object_destroy :1; /* Object being destroyed */
        !           206: #endif
        !           207:        queue_chain_t           cached_list;    /* Attachment point for the list
        !           208:                                                 * of objects cached as a result
        !           209:                                                 * of their can_persist value
        !           210:                                                 */
        !           211:        vm_offset_t             last_alloc;     /* last allocation offset */
        !           212: #if    MACH_PAGEMAP
        !           213:        vm_external_t           existence_info;
        !           214: #endif /* MACH_PAGEMAP */
        !           215: };
        !           216: 
        !           217: typedef struct vm_object       *vm_object_t;
        !           218: #define VM_OBJECT_NULL         ((vm_object_t) 0)
        !           219: 
        !           220: extern
        !           221: vm_object_t    kernel_object;          /* the single kernel object */
        !           222: 
        !           223: /*
        !           224:  *     Declare procedures that operate on VM objects.
        !           225:  */
        !           226: 
        !           227: #if    OLD_VM_CODE
        !           228: void           vm_object_init ();
        !           229: void           vm_object_terminate();
        !           230: vm_object_t    vm_object_allocate();
        !           231: void           vm_object_reference();
        !           232: void           vm_object_deallocate();
        !           233: void           vm_object_pmap_copy();
        !           234: void           vm_object_pmap_remove();
        !           235: void           vm_object_page_remove();
        !           236: void           vm_object_shadow();
        !           237: void           vm_object_copy();
        !           238: void           vm_object_collapse();
        !           239: vm_object_t    vm_object_lookup();
        !           240: port_t         vm_object_name();
        !           241: void           vm_object_enter();
        !           242: void           vm_object_setpager();
        !           243: kern_return_t  vm_object_cache_object();
        !           244: #define                vm_object_cache(pager)          vm_object_cache_object(vm_object_lookup(pager),TRUE)
        !           245: #define                vm_object_uncache(pager)        vm_object_cache_object(vm_object_lookup(pager),FALSE)
        !           246: 
        !           247: void           vm_object_cache_clear();
        !           248: int            vm_object_cache_steal();
        !           249: void           vm_object_print();
        !           250: 
        !           251: port_t         vm_object_request_port();
        !           252: vm_object_t    vm_object_request_object();
        !           253: #else
        !           254: extern void            vm_object_bootstrap(void);
        !           255: extern void            vm_object_init(void);
        !           256: extern void            vm_object_terminate(vm_object_t);
        !           257: extern vm_object_t     vm_object_allocate(vm_size_t);
        !           258: extern void            vm_object_reference(vm_object_t);
        !           259: extern void            vm_object_deallocate(vm_object_t);
        !           260: extern void            vm_object_pmap_protect(
        !           261:        vm_object_t     object,
        !           262:        vm_offset_t     offset,
        !           263:        vm_size_t       size,
        !           264:        pmap_t          pmap,
        !           265:        vm_offset_t     pmap_start,
        !           266:        vm_prot_t       prot);
        !           267: extern void            vm_object_pmap_remove(
        !           268:        vm_object_t     object,
        !           269:        vm_offset_t     start,
        !           270:        vm_offset_t     end);
        !           271: extern void            vm_object_page_remove(
        !           272:        vm_object_t     object,
        !           273:        vm_offset_t     start,
        !           274:        vm_offset_t     end);
        !           275: extern void            vm_object_shadow(
        !           276:        vm_object_t     *object,        /* in/out */
        !           277:        vm_offset_t     *offset,        /* in/out */
        !           278:        vm_size_t       length);
        !           279: extern void            vm_object_collapse(vm_object_t);
        !           280: extern vm_object_t     vm_object_lookup(struct ipc_port *);
        !           281: extern vm_object_t     vm_object_lookup_name(struct ipc_port *);
        !           282: extern struct ipc_port *vm_object_name(vm_object_t);
        !           283: extern void            vm_object_remove(vm_object_t);
        !           284: 
        !           285: extern boolean_t       vm_object_copy_temporary(
        !           286:        vm_object_t     *_object,               /* in/out */
        !           287:        vm_offset_t     *_offset,               /* in/out */
        !           288:        boolean_t       *_src_needs_copy,       /* out */
        !           289:        boolean_t       *_dst_needs_copy);      /* out */
        !           290: extern kern_return_t   vm_object_copy_strategically(
        !           291:        vm_object_t     src_object,
        !           292:        vm_offset_t     src_offset,
        !           293:        vm_size_t       size,
        !           294:        vm_object_t     *dst_object,            /* out */
        !           295:        vm_offset_t     *dst_offset,            /* out */
        !           296:        boolean_t       *dst_needs_copy);       /* out */
        !           297: extern kern_return_t   vm_object_copy_slowly(
        !           298:        vm_object_t     src_object,
        !           299:        vm_offset_t     src_offset,
        !           300:        vm_size_t       size,
        !           301:        boolean_t       interruptible,
        !           302:        vm_object_t     *_result_object);       /* out */
        !           303: 
        !           304: extern vm_object_t     vm_object_enter(
        !           305:        struct ipc_port *pager,
        !           306:        vm_size_t       size,
        !           307:        boolean_t       internal);
        !           308: extern void            vm_object_pager_create(
        !           309:        vm_object_t     object);
        !           310: extern void            vm_object_destroy(
        !           311:        struct ipc_port *pager);
        !           312: 
        !           313: extern void vm_object_page_map(        
        !           314:        vm_object_t, 
        !           315:         vm_offset_t, 
        !           316:         vm_size_t, 
        !           317:        vm_offset_t     (*)(void *, vm_offset_t),
        !           318:        void *);
        !           319: 
        !           320: extern void            vm_object_print(vm_object_t);
        !           321: 
        !           322: extern vm_object_t     vm_object_request_object(struct ipc_port *);
        !           323: 
        !           324: /*
        !           325:  *     Event waiting handling
        !           326:  */
        !           327: 
        !           328: #define        VM_OBJECT_EVENT_INITIALIZED             0
        !           329: #define        VM_OBJECT_EVENT_PAGER_READY             1
        !           330: #define        VM_OBJECT_EVENT_PAGING_IN_PROGRESS      2
        !           331: #define        VM_OBJECT_EVENT_ABSENT_COUNT            3
        !           332: #define        VM_OBJECT_EVENT_LOCK_IN_PROGRESS        4
        !           333: 
        !           334: #define        vm_object_wait(object, event, interruptible)                    \
        !           335:        MACRO_BEGIN                                                     \
        !           336:        (object)->all_wanted |= 1 << (event);                           \
        !           337:        vm_object_sleep(((vm_offset_t) object) + (event),               \
        !           338:                        (object),                                       \
        !           339:                        (interruptible));                               \
        !           340:        MACRO_END
        !           341: 
        !           342: #define        vm_object_assert_wait(object, event, interruptible)             \
        !           343:        MACRO_BEGIN                                                     \
        !           344:        (object)->all_wanted |= 1 << (event);                           \
        !           345:        assert_wait((event_t)(((vm_offset_t) object) + (event)), (interruptible));      \
        !           346:        MACRO_END
        !           347: 
        !           348: #define        vm_object_wakeup(object, event)                                 \
        !           349:        MACRO_BEGIN                                                     \
        !           350:        if ((object)->all_wanted & (1 << (event)))                      \
        !           351:                thread_wakeup((event_t)(((vm_offset_t) object) + (event)));     \
        !           352:        (object)->all_wanted &= ~(1 << (event));                        \
        !           353:        MACRO_END
        !           354: 
        !           355: /*
        !           356:  *     Routines implemented as macros
        !           357:  */
        !           358: 
        !           359: #define        vm_object_paging_begin(object)                                  \
        !           360:        ((object)->paging_in_progress++)
        !           361: 
        !           362: #define        vm_object_paging_end(object)                                    \
        !           363:        MACRO_BEGIN                                                     \
        !           364:        assert((object)->paging_in_progress != 0);                      \
        !           365:        if (--(object)->paging_in_progress == 0) {                      \
        !           366:                vm_object_wakeup(object,                                \
        !           367:                        VM_OBJECT_EVENT_PAGING_IN_PROGRESS);            \
        !           368:        }                                                               \
        !           369:        MACRO_END
        !           370: 
        !           371: #define        vm_object_paging_wait(object, interruptible)                    \
        !           372:        MACRO_BEGIN                                                     \
        !           373:        while ((object)->paging_in_progress != 0) {                     \
        !           374:                vm_object_wait( (object),                               \
        !           375:                                VM_OBJECT_EVENT_PAGING_IN_PROGRESS,     \
        !           376:                                (interruptible));                       \
        !           377:                vm_object_lock(object);                                 \
        !           378:                                                                        \
        !           379:          /*XXX if ((interruptible) &&  */                              \
        !           380:            /*XXX (current_thread()->wait_result != THREAD_AWAKENED))*/ \
        !           381:                  /*XXX break; */                                       \
        !           382:        }                                                               \
        !           383:        MACRO_END
        !           384: 
        !           385: #define        vm_object_absent_assert_wait(object, interruptible)             \
        !           386:        MACRO_BEGIN                                                     \
        !           387:        vm_object_assert_wait(  (object),                               \
        !           388:                        VM_OBJECT_EVENT_ABSENT_COUNT,                   \
        !           389:                        (interruptible));                               \
        !           390:        MACRO_END
        !           391: 
        !           392: 
        !           393: #define        vm_object_absent_release(object)                                \
        !           394:        MACRO_BEGIN                                                     \
        !           395:        (object)->absent_count--;                                       \
        !           396:        vm_object_wakeup((object),                                      \
        !           397:                         VM_OBJECT_EVENT_ABSENT_COUNT);                 \
        !           398:        MACRO_END
        !           399: #endif
        !           400: 
        !           401: /*
        !           402:  *     Object locking macros (with and without debugging)
        !           403:  */
        !           404: 
        !           405: #if    VM_OBJECT_DEBUG
        !           406: #define vm_object_lock_init(object) \
        !           407: MACRO_BEGIN \
        !           408:        simple_lock_init(&(object)->Lock); \
        !           409:        (object)->LockHolder = 0; \
        !           410: MACRO_END
        !           411: #define vm_object_lock(object) \
        !           412: MACRO_BEGIN \
        !           413:        simple_lock(&(object)->Lock); \
        !           414:        (object)->LockHolder = current_thread(); \
        !           415: MACRO_END
        !           416: #define vm_object_unlock(object) \
        !           417: MACRO_BEGIN \
        !           418:        if ((object)->LockHolder != current_thread()) \
        !           419:            panic("vm_object_unlock 0x%x", (object)); \
        !           420:        (object)->LockHolder = 0; \
        !           421:        simple_unlock(&(object)->Lock); \
        !           422: MACRO_END
        !           423: #define vm_object_lock_try(object) \
        !           424:        (simple_lock_try(&(object)->Lock) \
        !           425:            ? ( ((object)->LockHolder = current_thread()) , TRUE) \
        !           426:            : FALSE)
        !           427: #define vm_object_sleep(event, object, interruptible) \
        !           428: MACRO_BEGIN \
        !           429:        if ((object)->LockHolder != current_thread()) \
        !           430:            panic("vm_object_sleep %#x", (object)); \
        !           431:        (object)->LockHolder = 0; \
        !           432:        thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
        !           433:                (interruptible)); \
        !           434: MACRO_END
        !           435: #define        vm_object_lock_taken(object)    \
        !           436:                ((object)->LockHolder == current_thread())
        !           437: #else  /* VM_OBJECT_DEBUG */
        !           438: #define vm_object_lock_init(object)    simple_lock_init(&(object)->Lock)
        !           439: #define vm_object_lock(object)         simple_lock(&(object)->Lock)
        !           440: #define vm_object_unlock(object)       simple_unlock(&(object)->Lock)
        !           441: #define vm_object_lock_try(object)     simple_lock_try(&(object)->Lock)
        !           442: #define vm_object_sleep(event, object, interruptible)                  \
        !           443:                thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
        !           444:                             (interruptible))
        !           445: #define        vm_object_lock_taken(object)    simple_lock_taken(&(object)->Lock)
        !           446: #endif /* VM_OBJECT_DEBUG */
        !           447: 
        !           448: #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.