/*
- * 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@
*/
#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>
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;
(osize - 1) * sizeof(struct ipc_port_request));
} else {
osize = 1;
+ oits = 0;
free = 0;
}
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;
* 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);
}
/*
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 */
*/
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;
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)
{
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 */
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 */
/*
* 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;
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 */
}
}
/*
- * 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:
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);
}
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);
/*
#if MACH_ASSERT
+#include <kern/machine.h>
+
/*
* Keep a list of all allocated ports.
* Allocation is intercepted via ipc_port_init;
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);
}
{
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;
* 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 */
#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:
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;
ipc_object_print(&port->ip_object);
if (ipc_port_print_long) {
- iprintf("pool=0x%x", port->ip_thread_pool);
printf("\n");
}
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");
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)
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++;
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);
*
*/
-#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(
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);
#define ITEM_MAX 400
typedef struct port_track {
- char *name;
+ const char *name;
unsigned long max;
unsigned long warning;
port_item items[ITEM_MAX];
void port_track_init(
port_track *trackp,
- char *name);
+ const char *name);
void port_item_add(
port_track *trackp,
unsigned long item);
void
port_track_init(
port_track *trackp,
- char *name)
+ const char *name)
{
port_item *i;
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;
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))