Annotation of XNU/osfmk/kern/etap_pool.c, 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:  * HISTORY
        !            27:  * 
        !            28:  * Revision 1.1.1.1  1998/09/22 21:05:34  wsanchez
        !            29:  * Import of Mac OS X kernel (~semeria)
        !            30:  *
        !            31:  * Revision 1.1.1.1  1998/03/07 02:25:54  wsanchez
        !            32:  * Import of OSF Mach kernel (~mburg)
        !            33:  *
        !            34:  * Revision 1.1.12.1  1996/09/17  16:27:00  bruel
        !            35:  *     fixed bzero prototype.
        !            36:  *     [96/09/17            bruel]
        !            37:  *
        !            38:  * Revision 1.1.2.4  1995/10/09  17:13:51  devrcs
        !            39:  *     Merged in RT3_SHARED ETAP code.
        !            40:  *     [1995/09/13  18:34:15  joe]
        !            41:  * 
        !            42:  * Revision 1.1.2.3  1995/09/18  19:13:37  devrcs
        !            43:  *     Merged in RT3_SHARED ETAP code.
        !            44:  *     [1995/09/13  18:34:15  joe]
        !            45:  * 
        !            46:  * Revision 1.1.2.2  1995/01/10  05:11:15  devrcs
        !            47:  *     mk6 CR801 - merge up from nmk18b4 to nmk18b7
        !            48:  *     patch up spinlock references ==> simplelock
        !            49:  *     [1994/12/09  20:54:30  dwm]
        !            50:  * 
        !            51:  *     mk6 CR801 - new file for mk6_shared from cnmk_shared.
        !            52:  *     [1994/12/01  21:11:49  dwm]
        !            53:  * 
        !            54:  * Revision 1.1.2.1  1994/10/21  18:28:50  joe
        !            55:  *     Initial ETAP submission
        !            56:  *     [1994/10/20  19:31:33  joe]
        !            57:  * 
        !            58:  * $EndLog$
        !            59:  */
        !            60: /*
        !            61:  * File:       etap_pool.c
        !            62:  *
        !            63:  *             etap_pool.c contains the functions for maintenance
        !            64:  *             of the start_data_pool.   The start_data_pool is
        !            65:  *             used by the ETAP package.  Its primary
        !            66:  *             objective is to provide start_data_nodes to complex
        !            67:  *             locks so they can hold start information for read
        !            68:  *             locks  (since multiple readers can acquire a read
        !            69:  *             lock).   Each complex lock will maintain a linked
        !            70:  *             list of these nodes.
        !            71:  *
        !            72:  * NOTES:      The start_data_pool is used instead of zalloc to
        !            73:  *             eliminate complex lock dependancies.  If zalloc was used,
        !            74:  *             then no complex locks could be used in zalloc code paths.
        !            75:  *             This is both difficult and unrealistic, since zalloc
        !            76:  *             allocates memory dynamically. Hence, this dependancy is
        !            77:  *             eliminated with the use of the statically allocated
        !            78:  *             start_data_pool.
        !            79:  *
        !            80:  */
        !            81: 
        !            82: #include <kern/lock.h>
        !            83: #include <kern/spl.h>
        !            84: #include <kern/etap_pool.h>
        !            85: #include <kern/sched_prim.h>
        !            86: #include <kern/macro_help.h>
        !            87: 
        !            88: #if    ETAP_LOCK_TRACE
        !            89: 
        !            90: /*
        !            91:  *  Statically allocate the start data pool,
        !            92:  *  header and lock.
        !            93:  */
        !            94: 
        !            95: struct start_data_node  sd_pool [SD_POOL_ENTRIES];  /* static buffer */
        !            96: start_data_node_t       sd_free_list;   /* pointer to free node list */
        !            97: int                     sd_sleepers;    /* number of blocked threads */
        !            98: 
        !            99: simple_lock_data_t             sd_pool_lock;
        !           100: 
        !           101: 
        !           102: /*
        !           103:  *  Interrupts must be disabled while the 
        !           104:  *  sd_pool_lock is taken.
        !           105:  */
        !           106: 
        !           107: #define pool_lock(s)                   \
        !           108: MACRO_BEGIN                            \
        !           109:        s = splhigh();                  \
        !           110:        simple_lock(&sd_pool_lock);     \
        !           111: MACRO_END
        !           112: 
        !           113: #define pool_unlock(s)                 \
        !           114: MACRO_BEGIN                            \
        !           115:        simple_unlock(&sd_pool_lock);   \
        !           116:        splx(s);                        \
        !           117: MACRO_END
        !           118: 
        !           119: 
        !           120: /*
        !           121:  *  ROUTINE:    init_start_data_pool
        !           122:  *
        !           123:  *  FUNCTION:   Initialize the start_data_pool:
        !           124:  *              - create the free list chain for the max 
        !           125:  *                number of entries.
        !           126:  *              - initialize the sd_pool_lock
        !           127:  */
        !           128: 
        !           129: void
        !           130: init_start_data_pool(void)
        !           131: {
        !           132:        int x;
        !           133: 
        !           134:        simple_lock_init(&sd_pool_lock, ETAP_MISC_SD_POOL);
        !           135:     
        !           136:        /*
        !           137:         *  Establish free list pointer chain
        !           138:         */
        !           139: 
        !           140:        for (x=0; x < SD_POOL_ENTRIES-1; x++)
        !           141:                sd_pool[x].next = &sd_pool[x+1];
        !           142: 
        !           143:        sd_pool[SD_POOL_ENTRIES-1].next = SD_ENTRY_NULL;
        !           144:        sd_free_list  = &sd_pool[0];
        !           145:        sd_sleepers   = 0;
        !           146: }
        !           147: 
        !           148: /*
        !           149:  *  ROUTINE:    get_start_data_node
        !           150:  *
        !           151:  *  FUNCTION:   Returns a free node from the start data pool
        !           152:  *              to the caller.  If none are available, the
        !           153:  *              call will block, then try again.
        !           154:  */
        !           155: 
        !           156: start_data_node_t
        !           157: get_start_data_node(void)
        !           158: {
        !           159:        start_data_node_t avail_node;
        !           160:        spl_t             s;
        !           161: 
        !           162:        pool_lock(s);
        !           163: 
        !           164:        /*
        !           165:         *  If the pool does not have any nodes available,
        !           166:         *  block until one becomes free.
        !           167:         */
        !           168: 
        !           169:        while (sd_free_list == SD_ENTRY_NULL) {
        !           170: 
        !           171:                sd_sleepers++;
        !           172:                assert_wait((event_t) &sd_pool[0], THREAD_UNINT);
        !           173:                pool_unlock(s);
        !           174: 
        !           175:                printf ("DEBUG-KERNEL: empty start_data_pool\n");
        !           176:                thread_block((void (*)(void)) 0);
        !           177: 
        !           178:                pool_lock(s);
        !           179:                sd_sleepers--;
        !           180:        }
        !           181: 
        !           182:        avail_node   = sd_free_list;
        !           183:        sd_free_list = sd_free_list->next;
        !           184: 
        !           185:        pool_unlock(s);
        !           186: 
        !           187:        bzero ((char *) avail_node, sizeof(struct start_data_node)); 
        !           188:        avail_node->next = SD_ENTRY_NULL;
        !           189: 
        !           190:        return (avail_node);
        !           191: }
        !           192: 
        !           193: /*
        !           194:  *  ROUTINE:    free_start_data_node
        !           195:  *
        !           196:  *  FUNCTION:   Releases start data node back to the sd_pool,
        !           197:  *              so that it can be used again.
        !           198:  */
        !           199: 
        !           200: void
        !           201: free_start_data_node (
        !           202:        start_data_node_t   node)
        !           203: {
        !           204:        boolean_t   wakeup = FALSE;
        !           205:        spl_t       s;
        !           206: 
        !           207:        if (node == SD_ENTRY_NULL)
        !           208:                return;
        !           209: 
        !           210:        pool_lock(s);
        !           211: 
        !           212:        node->next   = sd_free_list;
        !           213:        sd_free_list = node;
        !           214: 
        !           215:        if (sd_sleepers)
        !           216:                wakeup = TRUE;
        !           217: 
        !           218:        pool_unlock(s);
        !           219: 
        !           220:        if (wakeup)
        !           221:                thread_wakeup((event_t) &sd_pool[0]);
        !           222: }
        !           223: 
        !           224: #endif /* ETAP_LOCK_TRACE */

unix.superglobalmegacorp.com

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