FreeBSD/Linux Kernel Cross Reference
sys/ipc/ipc_table.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1993,1992,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 Software.Distribution@CS.CMU.EDU
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 * HISTORY
28 * $Log: ipc_table.c,v $
29 * Revision 2.9 93/11/17 17:02:39 dbg
30 * Added ANSI function prototypes.
31 * [93/09/24 dbg]
32 *
33 * Revision 2.8 92/08/03 17:35:46 jfriedl
34 * removed silly prototypes
35 * [92/08/02 jfriedl]
36 *
37 * Revision 2.7 92/05/21 17:11:57 jfriedl
38 * tried prototypes.
39 * [92/05/20 jfriedl]
40 *
41 * Revision 2.6 91/10/09 16:11:08 af
42 * Removed unused variables.
43 * [91/09/02 rpd]
44 *
45 * Revision 2.5 91/05/14 16:37:35 mrt
46 * Correcting copyright
47 *
48 * Revision 2.4 91/03/16 14:48:52 rpd
49 * Added ipc_table_realloc and ipc_table_reallocable.
50 * [91/03/04 rpd]
51 *
52 * Revision 2.3 91/02/05 17:24:15 mrt
53 * Changed to new Mach copyright
54 * [91/02/01 15:52:05 mrt]
55 *
56 * Revision 2.2 90/06/02 14:51:58 rpd
57 * Created for new IPC.
58 * [90/03/26 21:04:20 rpd]
59 *
60 */
61 /*
62 * File: ipc/ipc_table.c
63 * Author: Rich Draves
64 * Date: 1989
65 *
66 * Functions to manipulate tables of IPC capabilities.
67 */
68
69 #include <mach/kern_return.h>
70 #include <mach/vm_param.h>
71 #include <ipc/ipc_table.h>
72 #include <ipc/ipc_port.h>
73 #include <ipc/ipc_entry.h>
74 #include <kern/kalloc.h>
75 #include <vm/vm_kern.h>
76
77
78
79 /*
80 * We borrow the kalloc map, rather than creating
81 * yet another submap of the kernel map.
82 */
83
84 extern vm_map_t kalloc_map;
85
86 ipc_table_size_t ipc_table_entries;
87 unsigned int ipc_table_entries_size = 128;
88
89 ipc_table_size_t ipc_table_dnrequests;
90 unsigned int ipc_table_dnrequests_size = 64;
91
92 void
93 ipc_table_fill(
94 ipc_table_size_t its, /* array to fill */
95 unsigned int num, /* size of array */
96 unsigned int min, /* at least this many elements */
97 vm_size_t elemsize) /* size of elements */
98 {
99 unsigned int index;
100 vm_size_t minsize = min * elemsize;
101 vm_size_t size;
102 vm_size_t incrsize;
103
104 /* first use powers of two, up to the page size */
105
106 for (index = 0, size = 1;
107 (index < num) && (size < PAGE_SIZE);
108 size <<= 1) {
109 if (size >= minsize) {
110 its[index].its_size = size / elemsize;
111 index++;
112 }
113 }
114
115 /* then increments of a page, then two pages, etc. */
116
117 for (incrsize = PAGE_SIZE; index < num; incrsize <<= 1) {
118 unsigned int period;
119
120 for (period = 0;
121 (period < 15) && (index < num);
122 period++, size += incrsize) {
123 if (size >= minsize) {
124 its[index].its_size = size / elemsize;
125 index++;
126 }
127 }
128 }
129 }
130
131 void
132 ipc_table_init(void)
133 {
134 ipc_table_entries = (ipc_table_size_t)
135 kalloc(sizeof(struct ipc_table_size) *
136 ipc_table_entries_size);
137 assert(ipc_table_entries != ITS_NULL);
138
139 ipc_table_fill(ipc_table_entries, ipc_table_entries_size - 1,
140 4, sizeof(struct ipc_entry));
141
142 /* the last two elements should have the same size */
143
144 ipc_table_entries[ipc_table_entries_size - 1].its_size =
145 ipc_table_entries[ipc_table_entries_size - 2].its_size;
146
147
148 ipc_table_dnrequests = (ipc_table_size_t)
149 kalloc(sizeof(struct ipc_table_size) *
150 ipc_table_dnrequests_size);
151 assert(ipc_table_dnrequests != ITS_NULL);
152
153 ipc_table_fill(ipc_table_dnrequests, ipc_table_dnrequests_size - 1,
154 2, sizeof(struct ipc_port_request));
155
156 /* the last element should have zero size */
157
158 ipc_table_dnrequests[ipc_table_dnrequests_size - 1].its_size = 0;
159 }
160
161 /*
162 * Routine: ipc_table_alloc
163 * Purpose:
164 * Allocate a table.
165 * Conditions:
166 * May block.
167 */
168
169 vm_offset_t
170 ipc_table_alloc(
171 vm_size_t size)
172 {
173 vm_offset_t table;
174
175 if (size < PAGE_SIZE)
176 table = kalloc(size);
177 else
178 if (kmem_alloc(kalloc_map, &table, size) != KERN_SUCCESS)
179 table = 0;
180
181 return table;
182 }
183
184 /*
185 * Routine: ipc_table_realloc
186 * Purpose:
187 * Reallocate a big table.
188 *
189 * The new table remaps the old table,
190 * so copying is not necessary.
191 * Conditions:
192 * Only works for page-size or bigger tables.
193 * May block.
194 */
195
196 vm_offset_t
197 ipc_table_realloc(
198 vm_size_t old_size,
199 vm_offset_t old_table,
200 vm_size_t new_size)
201 {
202 vm_offset_t new_table;
203
204 if (kmem_realloc(kalloc_map, old_table, old_size,
205 &new_table, new_size) != KERN_SUCCESS)
206 new_table = 0;
207
208 return new_table;
209 }
210
211 /*
212 * Routine: ipc_table_free
213 * Purpose:
214 * Free a table allocated with ipc_table_alloc or
215 * ipc_table_realloc.
216 * Conditions:
217 * May block.
218 */
219
220 void
221 ipc_table_free(
222 vm_size_t size,
223 vm_offset_t table)
224 {
225 if (size < PAGE_SIZE)
226 kfree(table, size);
227 else
228 kmem_free(kalloc_map, table, size);
229 }
Cache object: 8017fda1f2e9c7f4a36bf52782d81e2b
|