]> git.saurik.com Git - apple/xnu.git/blame - osfmk/ipc/ipc_table.c
xnu-344.49.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_table.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * @OSF_COPYRIGHT@
27 */
28/*
29 * HISTORY
30 *
31 * Revision 1.1.1.1 1998/09/22 21:05:28 wsanchez
32 * Import of Mac OS X kernel (~semeria)
33 *
34 * Revision 1.2 1998/06/01 17:29:25 youngwor
35 * Added infrastructure for shared port space support
36 *
37 * Revision 1.1.1.1 1998/03/07 02:26:16 wsanchez
38 * Import of OSF Mach kernel (~mburg)
39 *
40 * Revision 1.2.10.1 1994/09/23 02:12:16 ezf
41 * change marker to not FREE
42 * [1994/09/22 21:30:49 ezf]
43 *
44 * Revision 1.2.2.3 1993/07/22 16:17:30 rod
45 * Add ANSI prototypes. CR #9523.
46 * [1993/07/22 13:33:29 rod]
47 *
48 * Revision 1.2.2.2 1993/06/02 23:33:55 jeffc
49 * Added to OSF/1 R1.3 from NMK15.0.
50 * [1993/06/02 21:11:14 jeffc]
51 *
52 * Revision 1.2 1992/11/25 01:09:56 robert
53 * integrate changes below for norma_14
54 *
55 * Philippe Bernadat (bernadat) at gr.osf.org
56 * Limit ipc table allocation chunks to 8 pages, otherwise
57 * the kernel might dead lock because of VM_PAGE_FREE_RESERVED
58 * limited to 15. [dlb@osf.org & barbou@gr.osf.org]
59 * [1992/11/13 19:31:46 robert]
60 *
61 * Revision 1.1 1992/09/30 02:08:13 robert
62 * Initial revision
63 *
64 * $EndLog$
65 */
66/* CMU_HIST */
67/*
68 * Revision 2.6 91/10/09 16:11:08 af
69 * Revision 2.5.2.1 91/09/16 10:16:06 rpd
70 * Removed unused variables.
71 * [91/09/02 rpd]
72 *
73 * Revision 2.5.2.1 91/09/16 10:16:06 rpd
74 * Removed unused variables.
75 * [91/09/02 rpd]
76 *
77 * Revision 2.5 91/05/14 16:37:35 mrt
78 * Correcting copyright
79 *
80 * Revision 2.4 91/03/16 14:48:52 rpd
81 * Added ipc_table_realloc and ipc_table_reallocable.
82 * [91/03/04 rpd]
83 *
84 * Revision 2.3 91/02/05 17:24:15 mrt
85 * Changed to new Mach copyright
86 * [91/02/01 15:52:05 mrt]
87 *
88 * Revision 2.2 90/06/02 14:51:58 rpd
89 * Created for new IPC.
90 * [90/03/26 21:04:20 rpd]
91 *
92 */
93/* CMU_ENDHIST */
94/*
95 * Mach Operating System
96 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
97 * All Rights Reserved.
98 *
99 * Permission to use, copy, modify and distribute this software and its
100 * documentation is hereby granted, provided that both the copyright
101 * notice and this permission notice appear in all copies of the
102 * software, derivative works or modified versions, and any portions
103 * thereof, and that both notices appear in supporting documentation.
104 *
105 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
106 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
107 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
108 *
109 * Carnegie Mellon requests users of this software to return to
110 *
111 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
112 * School of Computer Science
113 * Carnegie Mellon University
114 * Pittsburgh PA 15213-3890
115 *
116 * any improvements or extensions that they make and grant Carnegie Mellon
117 * the rights to redistribute these changes.
118 */
119/*
120 */
121/*
122 * File: ipc/ipc_table.c
123 * Author: Rich Draves
124 * Date: 1989
125 *
126 * Functions to manipulate tables of IPC capabilities.
127 */
128
129#include <mach/kern_return.h>
130#include <mach/vm_param.h>
131#include <ipc/ipc_table.h>
132#include <ipc/ipc_port.h>
133#include <ipc/ipc_entry.h>
134#include <kern/kalloc.h>
135#include <vm/vm_kern.h>
136
137/*
138 * Forward declarations
139 */
140void ipc_table_fill(
141 ipc_table_size_t its,
142 unsigned int num,
143 unsigned int min,
144 vm_size_t elemsize);
145
146/*
147 * We borrow the kalloc map, rather than creating
148 * yet another submap of the kernel map.
149 */
150
151extern vm_map_t kalloc_map;
152
153ipc_table_size_t ipc_table_entries;
154unsigned int ipc_table_entries_size = 512;
155
156ipc_table_size_t ipc_table_dnrequests;
157unsigned int ipc_table_dnrequests_size = 64;
158
159void
160ipc_table_fill(
161 ipc_table_size_t its, /* array to fill */
162 unsigned int num, /* size of array */
163 unsigned int min, /* at least this many elements */
164 vm_size_t elemsize) /* size of elements */
165{
166 unsigned int index;
167 vm_size_t minsize = min * elemsize;
168 vm_size_t size;
169 vm_size_t incrsize;
170
171 /* first use powers of two, up to the page size */
172
173 for (index = 0, size = 1;
174 (index < num) && (size < PAGE_SIZE);
175 size <<= 1) {
176 if (size >= minsize) {
177 its[index].its_size = size / elemsize;
178 index++;
179 }
180 }
181
182 /* then increments of a page, then two pages, etc. */
183
184 for (incrsize = PAGE_SIZE; index < num;) {
185 unsigned int period;
186
187 for (period = 0;
188 (period < 15) && (index < num);
189 period++, size += incrsize) {
190 if (size >= minsize) {
191 its[index].its_size = size / elemsize;
192 index++;
193 }
194 }
195 if (incrsize < (PAGE_SIZE << 3))
196 incrsize <<= 1;
197 }
198}
199
200void
201ipc_table_init(void)
202{
203 ipc_table_entries = (ipc_table_size_t)
204 kalloc(sizeof(struct ipc_table_size) *
205 ipc_table_entries_size);
206 assert(ipc_table_entries != ITS_NULL);
207
208 ipc_table_fill(ipc_table_entries, ipc_table_entries_size - 1,
765c9de3 209 16, sizeof(struct ipc_entry));
1c79356b
A
210
211 /* the last two elements should have the same size */
212
213 ipc_table_entries[ipc_table_entries_size - 1].its_size =
214 ipc_table_entries[ipc_table_entries_size - 2].its_size;
215
216
217 ipc_table_dnrequests = (ipc_table_size_t)
218 kalloc(sizeof(struct ipc_table_size) *
219 ipc_table_dnrequests_size);
220 assert(ipc_table_dnrequests != ITS_NULL);
221
222 ipc_table_fill(ipc_table_dnrequests, ipc_table_dnrequests_size - 1,
223 2, sizeof(struct ipc_port_request));
224
225 /* the last element should have zero size */
226
227 ipc_table_dnrequests[ipc_table_dnrequests_size - 1].its_size = 0;
228}
229
230/*
231 * Routine: ipc_table_alloc
232 * Purpose:
233 * Allocate a table.
234 * Conditions:
235 * May block.
236 */
237
238vm_offset_t
239ipc_table_alloc(
240 vm_size_t size)
241{
242 vm_offset_t table;
243
244 if (size < PAGE_SIZE)
245 table = kalloc(size);
246 else
247 if (kmem_alloc(kalloc_map, &table, size) != KERN_SUCCESS)
248 table = 0;
249
250 return table;
251}
252
253/*
254 * Routine: ipc_table_realloc
255 * Purpose:
256 * Reallocate a big table.
257 *
258 * The new table remaps the old table,
259 * so copying is not necessary.
260 * Conditions:
261 * Only works for page-size or bigger tables.
262 * May block.
263 */
264
265vm_offset_t
266ipc_table_realloc(
267 vm_size_t old_size,
268 vm_offset_t old_table,
269 vm_size_t new_size)
270{
271 vm_offset_t new_table;
272
273 if (kmem_realloc(kalloc_map, old_table, old_size,
274 &new_table, new_size) != KERN_SUCCESS)
275 new_table = 0;
276
277 return new_table;
278}
279
280/*
281 * Routine: ipc_table_free
282 * Purpose:
283 * Free a table allocated with ipc_table_alloc or
284 * ipc_table_realloc.
285 * Conditions:
286 * May block.
287 */
288
289void
290ipc_table_free(
291 vm_size_t size,
292 vm_offset_t table)
293{
294 if (size < PAGE_SIZE)
295 kfree(table, size);
296 else
297 kmem_free(kalloc_map, table, size);
298}