|
|
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>
1.1.1.2 ! root 42: #include <kern/slab.h>
1.1 root 43: #include <vm/vm_kern.h>
44:
45: /*
46: * Forward declarations
47: */
48: void ipc_table_fill(
49: ipc_table_size_t its,
50: unsigned int num,
51: unsigned int min,
52: vm_size_t elemsize);
53:
54: ipc_table_size_t ipc_table_entries;
55: unsigned int ipc_table_entries_size = 512;
56:
57: ipc_table_size_t ipc_table_dnrequests;
58: unsigned int ipc_table_dnrequests_size = 64;
59:
60: void
61: ipc_table_fill(
62: ipc_table_size_t its, /* array to fill */
63: unsigned int num, /* size of array */
64: unsigned int min, /* at least this many elements */
65: vm_size_t elemsize) /* size of elements */
66: {
67: unsigned int index;
68: vm_size_t minsize = min * elemsize;
69: vm_size_t size;
70: vm_size_t incrsize;
71:
72: /* first use powers of two, up to the page size */
73:
74: for (index = 0, size = 1;
75: (index < num) && (size < PAGE_SIZE);
76: size <<= 1) {
77: if (size >= minsize) {
78: its[index].its_size = size / elemsize;
79: index++;
80: }
81: }
82:
83: /* then increments of a page, then two pages, etc. */
84:
85: for (incrsize = PAGE_SIZE; index < num;) {
86: unsigned int period;
87:
88: for (period = 0;
89: (period < 15) && (index < num);
90: period++, size += incrsize) {
91: if (size >= minsize) {
92: its[index].its_size = size / elemsize;
93: index++;
94: }
95: }
96: if (incrsize < (PAGE_SIZE << 3))
97: incrsize <<= 1;
98: }
99: }
100:
101: void
102: ipc_table_init(void)
103: {
104: ipc_table_entries = (ipc_table_size_t)
105: kalloc(sizeof(struct ipc_table_size) *
106: ipc_table_entries_size);
107: assert(ipc_table_entries != ITS_NULL);
108:
109: ipc_table_fill(ipc_table_entries, ipc_table_entries_size - 1,
110: 4, sizeof(struct ipc_entry));
111:
112: /* the last two elements should have the same size */
113:
114: ipc_table_entries[ipc_table_entries_size - 1].its_size =
115: ipc_table_entries[ipc_table_entries_size - 2].its_size;
116:
117:
118: ipc_table_dnrequests = (ipc_table_size_t)
119: kalloc(sizeof(struct ipc_table_size) *
120: ipc_table_dnrequests_size);
121: assert(ipc_table_dnrequests != ITS_NULL);
122:
123: ipc_table_fill(ipc_table_dnrequests, ipc_table_dnrequests_size - 1,
124: 2, sizeof(struct ipc_port_request));
125:
126: /* the last element should have zero size */
127:
128: ipc_table_dnrequests[ipc_table_dnrequests_size - 1].its_size = 0;
129: }
130:
131: /*
132: * Routine: ipc_table_alloc
133: * Purpose:
134: * Allocate a table.
135: * Conditions:
136: * May block.
137: */
138:
139: vm_offset_t
140: ipc_table_alloc(
141: vm_size_t size)
142: {
143: vm_offset_t table;
144:
145: if (size < PAGE_SIZE)
146: table = kalloc(size);
147: else
1.1.1.2 ! root 148: if (kmem_alloc(kmem_map, &table, size) != KERN_SUCCESS)
1.1 root 149: table = 0;
150:
151: return table;
152: }
153:
154: /*
155: * Routine: ipc_table_realloc
156: * Purpose:
157: * Reallocate a big table.
158: *
159: * The new table remaps the old table,
160: * so copying is not necessary.
161: * Conditions:
162: * Only works for page-size or bigger tables.
163: * May block.
164: */
165:
166: vm_offset_t
167: ipc_table_realloc(
168: vm_size_t old_size,
169: vm_offset_t old_table,
170: vm_size_t new_size)
171: {
172: vm_offset_t new_table;
173:
1.1.1.2 ! root 174: if (kmem_realloc(kmem_map, old_table, old_size,
1.1 root 175: &new_table, new_size) != KERN_SUCCESS)
176: new_table = 0;
177:
178: return new_table;
179: }
180:
181: /*
182: * Routine: ipc_table_free
183: * Purpose:
184: * Free a table allocated with ipc_table_alloc or
185: * ipc_table_realloc.
186: * Conditions:
187: * May block.
188: */
189:
190: void
191: ipc_table_free(
192: vm_size_t size,
193: vm_offset_t table)
194: {
195: if (size < PAGE_SIZE)
196: kfree(table, size);
197: else
1.1.1.2 ! root 198: kmem_free(kmem_map, table, size);
1.1 root 199: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.