The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/norma/xmm.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.