|
|
1.1 ! root 1: /* ! 2: * Mach Operating System ! 3: * Copyright (c) 1991,1990,1989 Carnegie Mellon University ! 4: * All Rights Reserved. ! 5: * ! 6: * Permission to use, copy, modify and distribute this software and its ! 7: * documentation is hereby granted, provided that both the copyright ! 8: * notice and this permission notice appear in all copies of the ! 9: * software, derivative works or modified versions, and any portions ! 10: * thereof, and that both notices appear in supporting documentation. ! 11: * ! 12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" ! 13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR ! 14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 15: * ! 16: * Carnegie Mellon requests users of this software to return to ! 17: * ! 18: * Software Distribution Coordinator or [email protected] ! 19: * School of Computer Science ! 20: * Carnegie Mellon University ! 21: * Pittsburgh PA 15213-3890 ! 22: * ! 23: * any improvements or extensions that they make and grant Carnegie Mellon ! 24: * the rights to redistribute these changes. ! 25: */ ! 26: /* ! 27: */ ! 28: /* ! 29: * File: ipc/ipc_table.c ! 30: * Author: Rich Draves ! 31: * Date: 1989 ! 32: * ! 33: * Functions to manipulate tables of IPC capabilities. ! 34: */ ! 35: ! 36: #include <mach/kern_return.h> ! 37: #include <mach/vm_param.h> ! 38: #include <ipc/ipc_table.h> ! 39: #include <ipc/ipc_port.h> ! 40: #include <ipc/ipc_entry.h> ! 41: #include <kern/kalloc.h> ! 42: #include <vm/vm_kern.h> ! 43: ! 44: /* ! 45: * Forward declarations ! 46: */ ! 47: void ipc_table_fill( ! 48: ipc_table_size_t its, ! 49: unsigned int num, ! 50: unsigned int min, ! 51: vm_size_t elemsize); ! 52: ! 53: /* ! 54: * We borrow the kalloc map, rather than creating ! 55: * yet another submap of the kernel map. ! 56: */ ! 57: ! 58: extern vm_map_t kalloc_map; ! 59: ! 60: ipc_table_size_t ipc_table_entries; ! 61: unsigned int ipc_table_entries_size = 512; ! 62: ! 63: ipc_table_size_t ipc_table_dnrequests; ! 64: unsigned int ipc_table_dnrequests_size = 64; ! 65: ! 66: void ! 67: ipc_table_fill( ! 68: ipc_table_size_t its, /* array to fill */ ! 69: unsigned int num, /* size of array */ ! 70: unsigned int min, /* at least this many elements */ ! 71: vm_size_t elemsize) /* size of elements */ ! 72: { ! 73: unsigned int index; ! 74: vm_size_t minsize = min * elemsize; ! 75: vm_size_t size; ! 76: vm_size_t incrsize; ! 77: ! 78: /* first use powers of two, up to the page size */ ! 79: ! 80: for (index = 0, size = 1; ! 81: (index < num) && (size < PAGE_SIZE); ! 82: size <<= 1) { ! 83: if (size >= minsize) { ! 84: its[index].its_size = size / elemsize; ! 85: index++; ! 86: } ! 87: } ! 88: ! 89: /* then increments of a page, then two pages, etc. */ ! 90: ! 91: for (incrsize = PAGE_SIZE; index < num;) { ! 92: unsigned int period; ! 93: ! 94: for (period = 0; ! 95: (period < 15) && (index < num); ! 96: period++, size += incrsize) { ! 97: if (size >= minsize) { ! 98: its[index].its_size = size / elemsize; ! 99: index++; ! 100: } ! 101: } ! 102: if (incrsize < (PAGE_SIZE << 3)) ! 103: incrsize <<= 1; ! 104: } ! 105: } ! 106: ! 107: void ! 108: ipc_table_init(void) ! 109: { ! 110: ipc_table_entries = (ipc_table_size_t) ! 111: kalloc(sizeof(struct ipc_table_size) * ! 112: ipc_table_entries_size); ! 113: assert(ipc_table_entries != ITS_NULL); ! 114: ! 115: ipc_table_fill(ipc_table_entries, ipc_table_entries_size - 1, ! 116: 4, sizeof(struct ipc_entry)); ! 117: ! 118: /* the last two elements should have the same size */ ! 119: ! 120: ipc_table_entries[ipc_table_entries_size - 1].its_size = ! 121: ipc_table_entries[ipc_table_entries_size - 2].its_size; ! 122: ! 123: ! 124: ipc_table_dnrequests = (ipc_table_size_t) ! 125: kalloc(sizeof(struct ipc_table_size) * ! 126: ipc_table_dnrequests_size); ! 127: assert(ipc_table_dnrequests != ITS_NULL); ! 128: ! 129: ipc_table_fill(ipc_table_dnrequests, ipc_table_dnrequests_size - 1, ! 130: 2, sizeof(struct ipc_port_request)); ! 131: ! 132: /* the last element should have zero size */ ! 133: ! 134: ipc_table_dnrequests[ipc_table_dnrequests_size - 1].its_size = 0; ! 135: } ! 136: ! 137: /* ! 138: * Routine: ipc_table_alloc ! 139: * Purpose: ! 140: * Allocate a table. ! 141: * Conditions: ! 142: * May block. ! 143: */ ! 144: ! 145: vm_offset_t ! 146: ipc_table_alloc( ! 147: vm_size_t size) ! 148: { ! 149: vm_offset_t table; ! 150: ! 151: if (size < PAGE_SIZE) ! 152: table = kalloc(size); ! 153: else ! 154: if (kmem_alloc(kalloc_map, &table, size) != KERN_SUCCESS) ! 155: table = 0; ! 156: ! 157: return table; ! 158: } ! 159: ! 160: /* ! 161: * Routine: ipc_table_realloc ! 162: * Purpose: ! 163: * Reallocate a big table. ! 164: * ! 165: * The new table remaps the old table, ! 166: * so copying is not necessary. ! 167: * Conditions: ! 168: * Only works for page-size or bigger tables. ! 169: * May block. ! 170: */ ! 171: ! 172: vm_offset_t ! 173: ipc_table_realloc( ! 174: vm_size_t old_size, ! 175: vm_offset_t old_table, ! 176: vm_size_t new_size) ! 177: { ! 178: vm_offset_t new_table; ! 179: ! 180: if (kmem_realloc(kalloc_map, old_table, old_size, ! 181: &new_table, new_size) != KERN_SUCCESS) ! 182: new_table = 0; ! 183: ! 184: return new_table; ! 185: } ! 186: ! 187: /* ! 188: * Routine: ipc_table_free ! 189: * Purpose: ! 190: * Free a table allocated with ipc_table_alloc or ! 191: * ipc_table_realloc. ! 192: * Conditions: ! 193: * May block. ! 194: */ ! 195: ! 196: void ! 197: ipc_table_free( ! 198: vm_size_t size, ! 199: vm_offset_t table) ! 200: { ! 201: if (size < PAGE_SIZE) ! 202: kfree(table, size); ! 203: else ! 204: kmem_free(kalloc_map, table, size); ! 205: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.