|
|
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 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.