]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ipc/ipc_port.c
xnu-792.6.56.tar.gz
[apple/xnu.git] / osfmk / ipc / ipc_port.c
index 7cd8a39f7792a0388c7413965f8e825666c744e7..d67c34c61ed6346df61fb299764129b95ccaf004 100644 (file)
@@ -1,21 +1,22 @@
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
@@ -66,9 +67,7 @@
 #include <mach/kern_return.h>
 #include <kern/lock.h>
 #include <kern/ipc_kobject.h>
-#include <kern/ipc_subsystem.h>
 #include <kern/thread.h>
-#include <kern/thread_pool.h>
 #include <kern/misc_protos.h>
 #include <kern/wait_queue.h>
 #include <ipc/ipc_entry.h>
@@ -187,8 +186,8 @@ ipc_port_dnrequest(
 
 kern_return_t
 ipc_port_dngrow(
-       ipc_port_t      port,
-       int             target_size)
+       ipc_port_t              port,
+       ipc_table_elems_t       target_size)
 {
        ipc_table_size_t its;
        ipc_port_request_t otable, ntable;
@@ -254,6 +253,7 @@ ipc_port_dngrow(
                              (osize - 1) * sizeof(struct ipc_port_request));
                } else {
                        osize = 1;
+                       oits = 0;
                        free = 0;
                }
 
@@ -296,9 +296,9 @@ ipc_port_dngrow(
 
 ipc_port_t
 ipc_port_dncancel(
-       ipc_port_t                      port,
-       mach_port_name_t                name,
-       ipc_port_request_index_t        index)
+       ipc_port_t                              port,
+       __assert_only mach_port_name_t  name,
+       ipc_port_request_index_t                index)
 {
        ipc_port_request_t ipr, table;
        ipc_port_t dnrequest;
@@ -413,8 +413,8 @@ ipc_port_clear_receiver(
         * pull ourselves from any sets.
         */
        if (port->ip_pset_count != 0) {
-               ipc_pset_remove_all(port);
-               port->ip_pset_count = 0;
+               ipc_pset_remove_from_all(port);
+               assert(port->ip_pset_count == 0);
        }
 
        /*
@@ -459,10 +459,6 @@ ipc_port_init(
        port->ip_pset_count = 0;
        port->ip_premsg = IKM_NULL;
 
-       thread_pool_init(&port->ip_thread_pool);
-
-       port->ip_subsystem = RPC_SUBSYSTEM_NULL;
-       
 #if    MACH_ASSERT
        ipc_port_init_debug(port);
 #endif /* MACH_ASSERT */
@@ -556,7 +552,7 @@ ipc_port_alloc_name(
  */
 void
 ipc_port_dnnotify(
-       ipc_port_t              port,
+       __unused ipc_port_t     port,
        ipc_port_request_t      dnrequests)
 {
        ipc_table_size_t        its = dnrequests->ipr_size;
@@ -565,7 +561,7 @@ ipc_port_dnnotify(
 
        for (index = 1; index < size; index++) {
                ipc_port_request_t      ipr = &dnrequests[index];
-               mach_port_name_t                name = ipr->ipr_name;
+               mach_port_name_t        name = ipr->ipr_name;
                ipc_port_t              soright;
 
                if (name == MACH_PORT_NULL)
@@ -599,10 +595,8 @@ ipc_port_destroy(
 {
        ipc_port_t pdrequest, nsrequest;
        ipc_mqueue_t mqueue;
-       ipc_kmsg_queue_t kmqueue;
        ipc_kmsg_t kmsg;
        ipc_port_request_t dnrequests;
-       thread_pool_t thread_pool;
 
        assert(ip_active(port));
        /* port->ip_receiver_name is garbage */
@@ -622,24 +616,9 @@ ipc_port_destroy(
                port->ip_destination = IP_NULL;
                ip_unlock(port);
 
-               if (!ipc_port_check_circularity(port, pdrequest)) {
-                       /* consumes our refs for port and pdrequest */
-                       ipc_notify_port_destroyed(pdrequest, port);
-                       return;
-               } else {
-                       /* consume pdrequest and destroy port */
-                       ipc_port_release_sonce(pdrequest);
-               }
-
-               ip_lock(port);
-               assert(ip_active(port));
-               assert(port->ip_pset_count == 0);
-               assert(port->ip_mscount == 0);
-               assert(port->ip_pdrequest == IP_NULL);
-               assert(port->ip_receiver_name == MACH_PORT_NULL);
-               assert(port->ip_destination == IP_NULL);
-
-               /* fall through and destroy the port */
+               /* consumes our refs for port and pdrequest */
+               ipc_notify_port_destroyed(pdrequest, port);
+               return;
        }
 
        /* once port is dead, we don't need to keep it locked */
@@ -653,30 +632,19 @@ ipc_port_destroy(
 
        /*
         * If the port has a preallocated message buffer and that buffer
-        * is not inuse, free it.  If it has and inuse one, then the kmsg
+        * is not inuse, free it.  If it has an inuse one, then the kmsg
         * free will detect that we freed the association and it can free it
         * like a normal buffer.
         */
        if (IP_PREALLOC(port)) {
                kmsg = port->ip_premsg;
                assert(kmsg != IKM_NULL);
-               if (!ikm_prealloc_inuse(kmsg)) {
-                       ikm_prealloc_clear_inuse(kmsg, port);
-                       IP_CLEAR_PREALLOC(port, kmsg);
+               IP_CLEAR_PREALLOC(port, kmsg);
+               if (!ikm_prealloc_inuse(kmsg))
                        ipc_kmsg_free(kmsg);
-               } else {
-                       assert(ikm_prealloc_inuse_port(kmsg) == port);
-                       ikm_prealloc_clear_inuse(kmsg, port);
-                       IP_CLEAR_PREALLOC(port, kmsg);
-               }
        }
-
        ip_unlock(port);
 
-       /* wakeup any threads waiting on this pool port for an activation */
-       if ((thread_pool = &port->ip_thread_pool) != THREAD_POOL_NULL)
-               thread_pool_wakeup(thread_pool);
-
        /* throw away no-senders request */
 
        nsrequest = port->ip_nsrequest;
@@ -694,12 +662,6 @@ ipc_port_destroy(
 
        ipc_kobject_destroy(port);
 
-       if (port->ip_subsystem != RPC_SUBSYSTEM_NULL) {
-               subsystem_deallocate((subsystem_t) port->ip_kobject);
-       }
-
-       /* XXXX Perhaps should verify that ip_thread_pool is empty! */
-
        ipc_port_release(port); /* consume caller's ref */
 }
 
@@ -888,29 +850,51 @@ ipc_port_lookup_notify(
 }
 
 /*
- *     Routine:        ipc_port_make_send
+ *     Routine:        ipc_port_make_send_locked
  *     Purpose:
  *             Make a naked send right from a receive right.
+ *
  *     Conditions:
- *             The port is not locked but it is active.
+ *             port locked and active.
  */
-
 ipc_port_t
-ipc_port_make_send(
+ipc_port_make_send_locked(
        ipc_port_t      port)
 {
-       assert(IP_VALID(port));
-
-       ip_lock(port);
        assert(ip_active(port));
        port->ip_mscount++;
        port->ip_srights++;
        ip_reference(port);
        ip_unlock(port);
-
        return port;
 }
 
+/*
+ *     Routine:        ipc_port_make_send
+ *     Purpose:
+ *             Make a naked send right from a receive right.
+ */
+
+ipc_port_t
+ipc_port_make_send(
+       ipc_port_t      port)
+{
+       
+       if (!IP_VALID(port))
+               return port;
+
+       ip_lock(port);
+       if (ip_active(port)) {
+               port->ip_mscount++;
+               port->ip_srights++;
+               ip_reference(port);
+               ip_unlock(port);
+               return port;
+       }
+       ip_unlock(port);
+       return IP_DEAD;
+}
+
 /*
  *     Routine:        ipc_port_copy_send
  *     Purpose:
@@ -1016,11 +1000,6 @@ ipc_port_release_send(
                mscount = port->ip_mscount;
                ip_unlock(port);
                ipc_notify_no_senders(nsrequest, mscount);
-               /*
-                * Check that there are no other locks taken, because
-                * [norma_]ipc_notify_no_senders routines may block.
-                */
-               check_simple_locks();
        } else
                ip_unlock(port);
 }
@@ -1153,12 +1132,12 @@ ipc_port_alloc_special(
 
 void
 ipc_port_dealloc_special(
-       ipc_port_t      port,
-       ipc_space_t     space)
+       ipc_port_t                      port,
+       __assert_only ipc_space_t       space)
 {
        ip_lock(port);
        assert(ip_active(port));
-       assert(port->ip_receiver_name != MACH_PORT_NULL);
+//     assert(port->ip_receiver_name != MACH_PORT_NULL);
        assert(port->ip_receiver == space);
 
        /*
@@ -1178,6 +1157,8 @@ ipc_port_dealloc_special(
 
 
 #if    MACH_ASSERT
+#include <kern/machine.h>
+
 /*
  *     Keep a list of all allocated ports.
  *     Allocation is intercepted via ipc_port_init;
@@ -1208,7 +1189,7 @@ void
 ipc_port_debug_init(void)
 {
        queue_init(&port_alloc_queue);
-       mutex_init(&port_alloc_queue_lock, ETAP_IPC_PORT_ALLOCQ);
+       mutex_init(&port_alloc_queue_lock, 0);
 }
 
 
@@ -1222,7 +1203,7 @@ ipc_port_init_debug(
 {
        unsigned int    i;
 
-       port->ip_thread = (unsigned long) current_thread();
+       port->ip_thread = current_thread();
        port->ip_timetrack = port_timestamp++;
        for (i = 0; i < IP_CALLSTACK_MAX; ++i)
                port->ip_callstack[i] = 0;
@@ -1252,18 +1233,24 @@ ipc_port_init_debug(
  *     This routine should be invoked JUST prior to
  *     deallocating the actual memory occupied by the port.
  */
+#if 1
 void
 ipc_port_track_dealloc(
-       ipc_port_t      port)
+       __unused ipc_port_t     port)
+{
+}
+#else
+void
+ipc_port_track_dealloc(
+       ipc_port_t              port)
 {
-#if 0
        mutex_lock(&port_alloc_queue_lock);
        assert(port_count > 0);
        --port_count;
        queue_remove(&port_alloc_queue, port, ipc_port_t, ip_port_links);
        mutex_unlock(&port_alloc_queue_lock);
-#endif
 }
+#endif
 
 #endif /* MACH_ASSERT */
 
@@ -1274,29 +1261,11 @@ ipc_port_track_dealloc(
 #include <ddb/db_print.h>
 
 #define        printf  kdbprintf
-extern int db_indent;
 
 int
 db_port_queue_print(
        ipc_port_t      port);
 
-/*
- * ipc_entry_print - pretty-print an ipc_entry
- */
-static void ipc_entry_print(struct ipc_entry *, char *); /* forward */
-
-static void ipc_entry_print(struct ipc_entry *iep, char *tag)
-{
-       ipc_entry_bits_t bits = iep->ie_bits;
-
-       iprintf("%s @", tag);
-       printf(" 0x%x, bits=%x object=%x\n", iep, bits, iep->ie_object);
-       db_indent += 2;
-       iprintf("urefs=%x ", IE_BITS_UREFS(bits));
-       printf("type=%x gen=%x\n", IE_BITS_TYPE(bits), IE_BITS_GEN(bits));
-       db_indent -= 2;
-}
-
 /*
  *     Routine:        ipc_port_print
  *     Purpose:
@@ -1306,12 +1275,11 @@ int     ipc_port_print_long = 0;        /* set for more detail */
 
 void
 ipc_port_print(
-       ipc_port_t      port,
-       boolean_t       have_addr,
-       db_expr_t       count,
-       char            *modif)
+       ipc_port_t              port,
+       __unused boolean_t      have_addr,
+       __unused db_expr_t      count,
+       char                    *modif)
 {
-       extern int      db_indent;
        db_addr_t       task;
        int             task_id;
        int             nmsgs;
@@ -1330,7 +1298,6 @@ ipc_port_print(
        ipc_object_print(&port->ip_object);
 
        if (ipc_port_print_long) {
-               iprintf("pool=0x%x", port->ip_thread_pool);
                printf("\n");
        }
 
@@ -1353,7 +1320,7 @@ ipc_port_print(
                        printf("reply");
                else if (port->ip_receiver == default_pager_space)
                        printf("default_pager");
-               else if (task = db_task_from_space(port->ip_receiver, &task_id))
+               else if ((task = db_task_from_space(port->ip_receiver, &task_id)) != (db_addr_t)0)
                        printf("task%d at 0x%x", task_id, task);
                else
                        printf("unknown");
@@ -1455,7 +1422,7 @@ print_type_ports(type, dead)
        for (port = (ipc_port_t)first_element(ipc_object_zones[IOT_PORT]);
             port;
             port = (ipc_port_t)next_element(ipc_object_zones[IOT_PORT], 
-                                            (vm_offset_t)port))
+                                            port))
                if (ip_kotype(port) == type &&
                    (!dead || !ip_active(port))) {
                        if (++n % 5)
@@ -1495,7 +1462,7 @@ print_ports(void)
        for (port = (ipc_port_t)first_element(ipc_object_zones[IOT_PORT]);
             port;
             port = (ipc_port_t)next_element(ipc_object_zones[IOT_PORT], 
-                                            (vm_offset_t)port)) {
+                                            port)) {
                total_port_count++;
                if (ip_kotype(port) >= IKOT_MAX_TYPE) {
                        port_types[IKOT_UNKNOWN].total_count++;
@@ -1535,8 +1502,8 @@ print_ports(void)
        PRINT_ONE_PORT_TYPE(PSET);
        PRINT_ONE_PORT_TYPE(PSET_NAME);
        PRINT_ONE_PORT_TYPE(PAGING_REQUEST);
-       PRINT_ONE_PORT_TYPE(XMM_OBJECT);
-       PRINT_ONE_PORT_TYPE(DEVICE);
+       PRINT_ONE_PORT_TYPE(MEMORY_OBJECT);
+       PRINT_ONE_PORT_TYPE(MIG);
        PRINT_ONE_PORT_TYPE(XMM_PAGER);
        PRINT_ONE_PORT_TYPE(XMM_KERNEL);
        PRINT_ONE_PORT_TYPE(XMM_REPLY);
@@ -1566,10 +1533,10 @@ print_ports(void)
  *
  */
 
-#define        KMSG_MATCH_FIELD(kmsg)  ((unsigned int) kmsg->ikm_header.msgh_id)
+#define        KMSG_MATCH_FIELD(kmsg)  (kmsg->ikm_header->msgh_id)
 #define        DKQP_LONG(kmsg) FALSE
-char   *dkqp_long_format = "(%3d) <%10d> 0x%x   %10d %10d\n";
-char   *dkqp_format = "(%3d) <%10d> 0x%x   %10d %10d\n";
+const char     *dkqp_long_format = "(%3d) <%10d> 0x%x   %10d %10d\n";
+const char     *dkqp_format = "(%3d) <%10d> 0x%x   %10d %10d\n";
 
 int
 db_kmsg_queue_print(
@@ -1604,7 +1571,7 @@ db_kmsg_queue_print(
                if (DKQP_LONG(kmsg))
                        inline_total += kmsg->ikm_size;
                else
-                       inline_total += kmsg->ikm_header.msgh_size;
+                       inline_total += kmsg->ikm_header->msgh_size;
        }
        iprintf(DKQP_LONG(kmsg) ? dkqp_long_format : dkqp_format,
                icount, cur_id, ikmsg, inline_total, ool_total);
@@ -1665,7 +1632,7 @@ typedef struct port_item {
 
 #define        ITEM_MAX        400
 typedef struct port_track {
-       char            *name;
+       const char      *name;
        unsigned long   max;
        unsigned long   warning;
        port_item       items[ITEM_MAX];
@@ -1677,7 +1644,7 @@ port_track        port_spaces;            /* match against ipc spaces */
 
 void           port_track_init(
                        port_track      *trackp,
-                       char            *name);
+                       const char      *name);
 void           port_item_add(
                        port_track      *trackp,
                        unsigned long   item);
@@ -1692,7 +1659,7 @@ void              port_callers_print(
 void
 port_track_init(
        port_track      *trackp,
-       char            *name)
+       const char      *name)
 {
        port_item       *i;
 
@@ -1814,7 +1781,6 @@ db_port_walk(
        unsigned int    ref_counts[MAX_REFS];
        unsigned int    inactive[MAX_REFS];
        unsigned int    ipc_ports = 0;
-       unsigned int    proxies = 0, principals = 0;
 
        iprintf("Allocated port count is %d\n", port_count);
        no_receiver = no_match = ref_overflow = 0;
@@ -1832,7 +1798,7 @@ db_port_walk(
                iprintf("Walking all ports.\n");
 
        queue_iterate(&port_alloc_queue, port, ipc_port_t, ip_port_links) {
-               char    *port_type;
+               const char *port_type;
 
                port_type = " IPC port";
                if (ip_active(port))