FreeBSD/Linux Kernel Cross Reference
sys/norma/xmm.c
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991 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
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 the
24 * rights to redistribute these changes.
25 */
26 /*
27 * HISTORY
28 * $Log: xmm.c,v $
29 * Revision 2.7 92/03/10 16:28:49 jsb
30 * Merged in norma branch changes as of NORMA_MK7.
31 * [92/03/09 12:50:54 jsb]
32 *
33 * Revision 2.6.2.5 92/02/21 14:34:51 jsb
34 * Fixed merge botch.
35 *
36 * Revision 2.6.2.4 92/02/21 11:25:25 jsb
37 * Disassociate and deallocate port in convert_port_to_reply.
38 * [92/02/18 17:33:30 jsb]
39 *
40 * Added multiple init detection code to xmm_kobj_link.
41 * Changed MACH_PORT_NULL uses to IP_NULL.
42 * [92/02/18 08:45:28 jsb]
43 *
44 * Changed reply->mobj to reply->kobj.
45 * Added reference counting to xmm_reply_{allocate,deallocate}.
46 * [92/02/16 18:25:51 jsb]
47 *
48 * Do real reference counting (except for xmm_replies).
49 * [92/02/16 14:11:32 jsb]
50 *
51 * Moved invocation routines to norma/xmm_invoke.c.
52 * Changed reply walking routines to use kobj, not mobj.
53 * Preparation for better reference counting on xmm objs.
54 * [92/02/09 12:53:36 jsb]
55 *
56 * Revision 2.6.2.3 92/02/18 19:17:22 jeffreyh
57 * Changed reply walking routines to use kobj, not mobj.
58 * Added xmm_buffer_init to norma_vm_init.
59 * [92/02/12 jsb]
60 *
61 * Revision 2.6.2.2 92/01/21 21:53:31 jsb
62 * Added xmm_reply_notify and (nonfunctional) xmm_reply_send_once.
63 * [92/01/21 18:23:51 jsb]
64 *
65 * De-linted. Added xmm_reply routines. Added functional forms of
66 * invocation routines. Added xmm_{obj,reply}_print routines.
67 * [92/01/20 17:13:30 jsb]
68 *
69 * Revision 2.6.2.1 92/01/03 16:38:38 jsb
70 * Corrected log.
71 * [91/12/24 14:33:43 jsb]
72 *
73 * Revision 2.6 91/12/10 13:26:21 jsb
74 * Added better debugging in xmm_obj_deallocate.
75 * [91/12/10 11:35:06 jsb]
76 *
77 * Revision 2.5 91/11/14 16:52:32 rpd
78 * Added missing argument to bcopy.
79 * [91/11/00 jsb]
80 *
81 * Revision 2.4 91/08/03 18:19:37 jsb
82 * Renamed xmm_init() to norma_vm_init().
83 * [91/07/24 23:25:57 jsb]
84 *
85 * Revision 2.3 91/07/01 08:25:56 jsb
86 * Removed non-KERNEL code.
87 * Replaced Xobj_allocate with xmm_obj_allocate.
88 * Added xmm_obj_deallocate.
89 * Use per-class zone for obj allocation.
90 * [91/06/29 15:21:33 jsb]
91 *
92 * Revision 2.2 91/06/17 15:48:10 jsb
93 * First checkin.
94 * [91/06/17 10:58:38 jsb]
95 *
96 */
97 /*
98 * File: norma/xmm.c
99 * Author: Joseph S. Barrera III
100 * Date: 1991
101 *
102 * Common xmm support routines.
103 */
104
105 #include <norma/xmm_obj.h>
106 #include <mach/notify.h>
107 #include <ipc/ipc_space.h>
108 #include <ipc/ipc_port.h>
109
110 zone_t xmm_reply_zone;
111
112 #define OBJ_SETQ(lhs_obj, rhs_obj)\
113 ((rhs_obj)->refcount++, (int)((lhs_obj) = (rhs_obj)))
114
115 /*
116 * If caller provides old_mobj, then he donates a reference.
117 * Returns a reference for new_mobj to caller.
118 */
119 kern_return_t
120 xmm_obj_allocate(class, old_mobj, new_mobj)
121 xmm_class_t class;
122 xmm_obj_t old_mobj;
123 xmm_obj_t *new_mobj;
124 {
125 xmm_obj_t mobj;
126
127 if (class->c_zone == ZONE_NULL) {
128 char *zone_name;
129
130 zone_name = (char *)
131 kalloc((vm_size_t) (strlen(class->c_name) + 5));
132 bcopy("xmm.", zone_name, 4);
133 bcopy(class->c_name, zone_name + 4, strlen(class->c_name) + 1);
134 class->c_zone = zinit(class->c_size, 512*1024, class->c_size,
135 FALSE, zone_name);
136 }
137 mobj = (xmm_obj_t) zalloc(class->c_zone);
138 bzero((char *) mobj, class->c_size);
139 mobj->class = class;
140 mobj->refcount = 1;
141 mobj->m_kobj = XMM_OBJ_NULL;
142 mobj->k_kobj = XMM_OBJ_NULL;
143 if (old_mobj) {
144 OBJ_SETQ(mobj->m_mobj, old_mobj);
145 OBJ_SETQ(old_mobj->k_mobj, mobj);
146 xmm_obj_release(old_mobj); /* release caller's reference */
147 } else {
148 mobj->m_mobj = XMM_OBJ_NULL;
149 }
150 *new_mobj = mobj;
151 return KERN_SUCCESS;
152 }
153
154 /*
155 * XXX
156 * REPLACE THIS COMMENT
157 *
158 * Termination protocol:
159 * Each layer terminates layer beneath it before deallocating.
160 * Bottom layers disable outside upcalls before blocking.
161 * (For example, xmm_user.c does kobject_set(NULL) before
162 * calling memory_object_terminate.)
163 */
164
165 xmm_kobj_link(kobj, k_kobj)
166 xmm_obj_t kobj;
167 xmm_obj_t k_kobj;
168 {
169 assert(k_kobj->m_kobj == XMM_OBJ_NULL);
170 if (kobj->k_kobj != XMM_OBJ_NULL) {
171 panic("xmm_kobj_link: multiple init");
172 }
173 OBJ_SETQ(k_kobj->m_kobj, kobj);
174 OBJ_SETQ(kobj->k_kobj, k_kobj);
175 }
176
177 xmm_obj_unlink(mobj, kobj)
178 xmm_obj_t mobj;
179 xmm_obj_t kobj;
180 {
181 register xmm_obj_t m_mobj = mobj->m_mobj;
182 register xmm_obj_t m_kobj = kobj->m_kobj;
183
184 assert(m_mobj != XMM_OBJ_NULL);
185 mobj->m_mobj = XMM_OBJ_NULL;
186 assert(m_kobj != XMM_OBJ_NULL);
187 kobj->m_kobj = XMM_OBJ_NULL;
188 xmm_obj_release(m_mobj);
189 xmm_obj_release(m_kobj);
190 }
191
192 xmm_obj_reference(obj)
193 xmm_obj_t obj;
194 {
195 obj->refcount++;
196 }
197
198 xmm_obj_release(obj)
199 xmm_obj_t obj;
200 {
201 assert(obj->refcount > 0);
202 if (--obj->refcount == 0) {
203 assert(obj->m_mobj == XMM_OBJ_NULL);
204 assert(obj->m_kobj == XMM_OBJ_NULL);
205 if (obj->k_mobj) {
206 xmm_obj_release(obj->k_mobj);
207 obj->k_mobj = XMM_OBJ_NULL;
208 }
209 if (obj->k_kobj) {
210 xmm_obj_release(obj->k_kobj);
211 obj->k_kobj = XMM_OBJ_NULL;
212 }
213 obj->class->m_deallocate(obj);
214 zfree(obj->class->c_zone, (vm_offset_t) obj);
215 }
216 }
217
218 kern_return_t
219 xmm_reply_allocate(kobj, reply_to, reply_to_type, new_reply)
220 xmm_obj_t kobj;
221 ipc_port_t reply_to;
222 mach_msg_type_name_t reply_to_type;
223 xmm_reply_t *new_reply;
224 {
225 register xmm_reply_t reply;
226
227 if (reply_to == IP_NULL) {
228 *new_reply = XMM_REPLY_NULL;
229 return KERN_SUCCESS;
230 }
231 reply = (xmm_reply_t) zalloc(xmm_reply_zone);
232 reply->kobj = kobj;
233 reply->reply_to = reply_to;
234 reply->reply_to_type = reply_to_type;
235 reply->reply_proxy = IP_NULL;
236 OBJ_SETQ(reply->kobj_held, kobj);
237 *new_reply = reply;
238 return KERN_SUCCESS;
239 }
240
241 xmm_reply_deallocate(reply)
242 xmm_reply_t reply;
243 {
244 xmm_obj_release(reply->kobj_held);
245 zfree(xmm_reply_zone, (vm_offset_t) reply);
246 }
247
248 /*
249 * XXX
250 * The same proxy could be used over and over again. Perhaps should
251 * have a pool of xmm_replies, with reply_proxies always allocated,
252 * and eliminate this routine.
253 */
254 kern_return_t
255 xmm_reply_allocate_proxy(reply)
256 xmm_reply_t reply;
257 {
258 if (reply == XMM_REPLY_NULL) {
259 return KERN_SUCCESS;
260 }
261 assert(reply->reply_proxy == IP_NULL);
262 reply->reply_proxy = ipc_port_alloc_kernel();
263 if (reply->reply_proxy == IP_NULL) {
264 panic("xmm_reply_allocate_proxy");
265 return KERN_FAILURE;
266 }
267 ipc_kobject_set(reply->reply_proxy, (ipc_kobject_t) reply,
268 IKOT_XMM_REPLY);
269 return KERN_SUCCESS;
270 }
271
272 /*
273 * Finds reply corresponding to port.
274 * Disassociates port from reply and deallocates port.
275 */
276 xmm_reply_t
277 convert_port_to_reply(port)
278 ipc_port_t port;
279 {
280 xmm_reply_t reply = XMM_REPLY_NULL;
281
282 if (IP_VALID(port)) {
283 ip_lock(port);
284 if (ip_active(port) && ip_kotype(port) == IKOT_XMM_REPLY) {
285 reply = (xmm_reply_t) port->ip_kobject;
286 ipc_kobject_set(port, IKO_NULL, IKOT_NONE);
287 assert(reply->reply_proxy == port);
288 reply->reply_proxy = IP_NULL;
289 }
290 ip_unlock(port);
291 ipc_port_dealloc_kernel(port);
292 }
293 return reply;
294 }
295
296 /*
297 * XXX
298 * This is nice, but how do we find the intended destination of this reply?
299 */
300 xmm_reply_send_once(notification)
301 mach_send_once_notification_t *notification;
302 {
303 panic("xmm_reply_no_senders");
304 }
305
306 boolean_t
307 xmm_reply_notify(msg)
308 mach_msg_header_t *msg;
309 {
310 switch (msg->msgh_id) {
311 case MACH_NOTIFY_SEND_ONCE:
312 xmm_reply_send_once((mach_send_once_notification_t *) msg);
313 return TRUE;
314
315 default:
316 printf("ds_notify: strange notification %d\n", msg->msgh_id);
317 return FALSE;
318 }
319 }
320
321 xmm_reply_t
322 xmm_k_reply(reply)
323 xmm_reply_t reply;
324 {
325 if (reply != XMM_REPLY_NULL) {
326 assert(reply->kobj != XMM_OBJ_NULL);
327 reply->kobj = reply->kobj->k_kobj;
328 assert(reply->kobj != XMM_OBJ_NULL);
329 }
330 return reply;
331 }
332
333 xmm_class_t
334 xmm_m_reply(reply)
335 xmm_reply_t reply;
336 {
337 assert(reply->kobj != XMM_OBJ_NULL);
338 reply->kobj = reply->kobj->m_kobj;
339 assert(reply->kobj != XMM_OBJ_NULL);
340 return reply->kobj->class;
341 }
342
343 norma_vm_init()
344 {
345 xmm_svm_init();
346 xmm_split_init();
347 xmm_buffer_init();
348 xmm_reply_zone = zinit(sizeof(struct xmm_reply), 512*1024,
349 sizeof(struct xmm_reply), FALSE, "xmm_reply");
350 }
351
352 #include <mach_kdb.h>
353 #if MACH_KDB
354 #define printf kdbprintf
355
356 /*
357 * Routine: xmm_obj_print
358 * Purpose:
359 * Pretty-print an xmm obj.
360 */
361
362 void
363 xmm_obj_print(obj)
364 xmm_obj_t obj;
365 {
366 extern int indent;
367
368 printf("xmm obj 0x%x\n", obj);
369
370 indent += 2;
371
372 iprintf("class=0x%x[%s]", obj->class, obj->class->c_name);
373 printf(", refcount=%d\n", obj->refcount);
374
375 iprintf("m_mobj=0x%x", obj->m_mobj);
376 printf(", m_kobj=0x%x", obj->m_kobj);
377 printf(", k_mobj=0x%x", obj->k_mobj);
378 printf(", k_kobj=0x%x\n", obj->k_kobj);
379
380 indent -=2;
381 }
382
383 /*
384 * Routine: xmm_reply_print
385 * Purpose:
386 * Pretty-print an xmm reply.
387 */
388
389 void
390 xmm_reply_print(reply)
391 xmm_reply_t reply;
392 {
393 extern int indent;
394
395 printf("xmm reply 0x%x\n", reply);
396
397 indent += 2;
398
399 iprintf("reply_to=0x%x", reply->reply_to);
400 printf(", reply_to_type=%d[", reply->reply_to_type);
401 switch (reply->reply_to_type) {
402 case MACH_MSG_TYPE_PORT_SEND:
403 printf("send");
404 break;
405
406 case MACH_MSG_TYPE_PORT_SEND_ONCE:
407 printf("send_once");
408 break;
409
410 case XMM_SVM_REPLY:
411 printf("svm");
412 break;
413
414 case XMM_SPLIT_REPLY:
415 printf("split");
416 break;
417
418 default:
419 printf("???");
420 break;
421 }
422 printf("]\n");
423
424 iprintf("kobj=0x%x", reply->kobj);
425 printf(", kobj_held=0x%x", reply->kobj_held);
426 printf(", reply_proxy=0x%x\n", reply->reply_proxy);
427
428 indent -=2;
429 }
430
431 #endif MACH_KDB
Cache object: 3384e15383cefcc1f0d06cd03efe8676
|