1 /*
2 * Copyright 1991-1998 by Open Software Foundation, Inc.
3 * All Rights Reserved
4 *
5 * Permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby granted,
7 * provided that the above copyright notice appears in all copies and
8 * that both the copyright notice and this permission notice appear in
9 * supporting documentation.
10 *
11 * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
12 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
14 *
15 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
16 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
17 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
18 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
19 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21 /*
22 * MkLinux
23 */
24 /* CMU_HIST */
25 /*
26 * Revision 2.6 91/10/09 16:11:08 af
27 * Revision 2.5.2.1 91/09/16 10:16:06 rpd
28 * Removed unused variables.
29 * [91/09/02 rpd]
30 *
31 * Revision 2.5.2.1 91/09/16 10:16:06 rpd
32 * Removed unused variables.
33 * [91/09/02 rpd]
34 *
35 * Revision 2.5 91/05/14 16:37:35 mrt
36 * Correcting copyright
37 *
38 * Revision 2.4 91/03/16 14:48:52 rpd
39 * Added ipc_table_realloc and ipc_table_reallocable.
40 * [91/03/04 rpd]
41 *
42 * Revision 2.3 91/02/05 17:24:15 mrt
43 * Changed to new Mach copyright
44 * [91/02/01 15:52:05 mrt]
45 *
46 * Revision 2.2 90/06/02 14:51:58 rpd
47 * Created for new IPC.
48 * [90/03/26 21:04:20 rpd]
49 *
50 */
51 /* CMU_ENDHIST */
52 /*
53 * Mach Operating System
54 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
55 * All Rights Reserved.
56 *
57 * Permission to use, copy, modify and distribute this software and its
58 * documentation is hereby granted, provided that both the copyright
59 * notice and this permission notice appear in all copies of the
60 * software, derivative works or modified versions, and any portions
61 * thereof, and that both notices appear in supporting documentation.
62 *
63 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
64 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
65 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
66 *
67 * Carnegie Mellon requests users of this software to return to
68 *
69 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
70 * School of Computer Science
71 * Carnegie Mellon University
72 * Pittsburgh PA 15213-3890
73 *
74 * any improvements or extensions that they make and grant Carnegie Mellon
75 * the rights to redistribute these changes.
76 */
77 /*
78 */
79 /*
80 * File: ipc/ipc_table.c
81 * Author: Rich Draves
82 * Date: 1989
83 *
84 * Functions to manipulate tables of IPC capabilities.
85 */
86
87 #include <sys/cdefs.h>
88 #include <sys/types.h>
89 #include <sys/param.h>
90 #include <sys/mach/mach_types.h>
91 #include <sys/mach/kern_return.h>
92 #if 0
93 #include <mach/vm_param.h>
94 #endif
95 #include <sys/mach/ipc/ipc_table.h>
96 #include <sys/mach/ipc/ipc_port.h>
97 #include <sys/mach/ipc/ipc_entry.h>
98 #if 0
99 #include <kern/kalloc.h>
100 #include <vm/vm_kern.h>
101 #endif
102 /*
103 * Forward declarations
104 */
105 void ipc_table_fill(
106 ipc_table_size_t its,
107 unsigned int num,
108 unsigned int min,
109 vm_size_t elemsize);
110
111 /*
112 * We borrow the kalloc map, rather than creating
113 * yet another submap of the kernel map.
114 */
115
116 extern vm_map_t kalloc_map;
117
118 ipc_table_size_t ipc_table_entries;
119 unsigned int ipc_table_entries_size = 512;
120
121 ipc_table_size_t ipc_table_dnrequests;
122 unsigned int ipc_table_dnrequests_size = 64;
123
124 void
ipc_table_fill(ipc_table_size_t its,unsigned int num,unsigned int min,vm_size_t elemsize)125 ipc_table_fill(
126 ipc_table_size_t its, /* array to fill */
127 unsigned int num, /* size of array */
128 unsigned int min, /* at least this many elements */
129 vm_size_t elemsize) /* size of elements */
130 {
131 unsigned int index;
132 vm_size_t minsize = min * elemsize;
133 vm_size_t size;
134 vm_size_t incrsize;
135
136 /* first use powers of two, up to the page size */
137
138 for (index = 0, size = 1;
139 (index < num) && (size < PAGE_SIZE);
140 size <<= 1) {
141 if (size >= minsize) {
142 its[index].its_size = size / elemsize;
143 index++;
144 }
145 }
146
147 /* then increments of a page, then two pages, etc. */
148
149 for (incrsize = PAGE_SIZE; index < num;) {
150 unsigned int period;
151
152 for (period = 0;
153 (period < 15) && (index < num);
154 period++, size += incrsize) {
155 if (size >= minsize) {
156 its[index].its_size = size / elemsize;
157 index++;
158 }
159 }
160 if (incrsize < (PAGE_SIZE << 3))
161 incrsize <<= 1;
162 }
163 }
164
165 void
ipc_table_init(void)166 ipc_table_init(void)
167 {
168 ipc_table_entries = (ipc_table_size_t)
169 kalloc(sizeof(struct ipc_table_size) *
170 ipc_table_entries_size);
171 assert(ipc_table_entries != ITS_NULL);
172
173 ipc_table_fill(ipc_table_entries, ipc_table_entries_size - 1,
174 4, sizeof(struct ipc_entry));
175
176 /* the last two elements should have the same size */
177
178 ipc_table_entries[ipc_table_entries_size - 1].its_size =
179 ipc_table_entries[ipc_table_entries_size - 2].its_size;
180
181
182 ipc_table_dnrequests = (ipc_table_size_t)
183 kalloc(sizeof(struct ipc_table_size) *
184 ipc_table_dnrequests_size);
185 assert(ipc_table_dnrequests != ITS_NULL);
186
187 ipc_table_fill(ipc_table_dnrequests, ipc_table_dnrequests_size - 1,
188 2, sizeof(struct ipc_port_request));
189
190 /* the last element should have zero size */
191
192 ipc_table_dnrequests[ipc_table_dnrequests_size - 1].its_size = 0;
193 }
194
195 /*
196 * Routine: ipc_table_alloc
197 * Purpose:
198 * Allocate a table.
199 * Conditions:
200 * May block.
201 */
202
203 vm_offset_t
ipc_table_alloc(vm_size_t size)204 ipc_table_alloc(
205 vm_size_t size)
206 {
207
208 return ((vm_offset_t)malloc(size, M_MACH_IPC_TABLE, M_ZERO|M_WAITOK));
209 }
210
211 /*
212 * Routine: ipc_table_realloc
213 * Purpose:
214 * Reallocate a big table.
215 *
216 * The new table remaps the old table,
217 * so copying is not necessary.
218 * Conditions:
219 * Only works for page-size or bigger tables.
220 * May block.
221 */
222
223 vm_offset_t
ipc_table_realloc(vm_size_t old_size __unused,vm_offset_t old_table,vm_size_t new_size)224 ipc_table_realloc(
225 vm_size_t old_size __unused,
226 vm_offset_t old_table,
227 vm_size_t new_size)
228 {
229
230 return ((vm_offset_t)realloc((void*)old_table, new_size, M_MACH_IPC_TABLE, M_WAITOK));
231 }
232
233 /*
234 * Routine: ipc_table_free
235 * Purpose:
236 * Free a table allocated with ipc_table_alloc or
237 * ipc_table_realloc.
238 * Conditions:
239 * May block.
240 */
241
242 void
ipc_table_free(vm_size_t size __unused,vm_offset_t table)243 ipc_table_free(
244 vm_size_t size __unused,
245 vm_offset_t table)
246 {
247
248 free((void *)table, M_MACH_IPC_TABLE);
249 }
250