|
|
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.