X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..5d5c5d0d5b79ade9a973d55186ffda2638ba2b6e:/osfmk/ipc/ipc_port.c diff --git a/osfmk/ipc/ipc_port.c b/osfmk/ipc/ipc_port.c index 989d73b81..a11533515 100644 --- a/osfmk/ipc/ipc_port.c +++ b/osfmk/ipc/ipc_port.c @@ -1,23 +1,31 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ + * @APPLE_LICENSE_OSREFERENCE_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 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. - * - * @APPLE_LICENSE_HEADER_END@ + * 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. The rights granted to you under the + * License may not be used to create, or enable the creation or + * redistribution of, unlawful or unlicensed copies of an Apple operating + * system, or to circumvent, violate, or enable the circumvention or + * violation of, any terms of an Apple operating system software license + * agreement. + * + * Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * 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, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_OSREFERENCE_HEADER_END@ */ /* * @OSF_FREE_COPYRIGHT@ @@ -66,9 +74,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -187,8 +193,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 +260,7 @@ ipc_port_dngrow( (osize - 1) * sizeof(struct ipc_port_request)); } else { osize = 1; + oits = 0; free = 0; } @@ -296,9 +303,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 +420,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 +466,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 +559,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 +568,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 +602,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 +623,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 +639,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 +669,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 */ } @@ -1038,11 +1007,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); } @@ -1175,12 +1139,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); /* @@ -1200,6 +1164,8 @@ ipc_port_dealloc_special( #if MACH_ASSERT +#include + /* * Keep a list of all allocated ports. * Allocation is intercepted via ipc_port_init; @@ -1230,7 +1196,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); } @@ -1244,7 +1210,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; @@ -1274,18 +1240,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 */ @@ -1296,29 +1268,11 @@ ipc_port_track_dealloc( #include #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: @@ -1328,12 +1282,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; @@ -1352,7 +1305,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"); } @@ -1375,7 +1327,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"); @@ -1477,7 +1429,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) @@ -1517,7 +1469,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++; @@ -1556,15 +1508,32 @@ print_ports(void) PRINT_ONE_PORT_TYPE(PROCESSOR); PRINT_ONE_PORT_TYPE(PSET); PRINT_ONE_PORT_TYPE(PSET_NAME); + PRINT_ONE_PORT_TYPE(TIMER); PRINT_ONE_PORT_TYPE(PAGING_REQUEST); - PRINT_ONE_PORT_TYPE(MEMORY_OBJECT); PRINT_ONE_PORT_TYPE(MIG); + PRINT_ONE_PORT_TYPE(MEMORY_OBJECT); PRINT_ONE_PORT_TYPE(XMM_PAGER); PRINT_ONE_PORT_TYPE(XMM_KERNEL); PRINT_ONE_PORT_TYPE(XMM_REPLY); + PRINT_ONE_PORT_TYPE(UND_REPLY); + PRINT_ONE_PORT_TYPE(HOST_NOTIFY); + PRINT_ONE_PORT_TYPE(HOST_SECURITY); + PRINT_ONE_PORT_TYPE(LEDGER); + PRINT_ONE_PORT_TYPE(MASTER_DEVICE); + PRINT_ONE_PORT_TYPE(TASK_NAME); + PRINT_ONE_PORT_TYPE(SUBSYSTEM); + PRINT_ONE_PORT_TYPE(IO_DONE_QUEUE); + PRINT_ONE_PORT_TYPE(SEMAPHORE); + PRINT_ONE_PORT_TYPE(LOCK_SET); PRINT_ONE_PORT_TYPE(CLOCK); PRINT_ONE_PORT_TYPE(CLOCK_CTRL); - PRINT_ONE_PORT_TYPE(MASTER_DEVICE); + PRINT_ONE_PORT_TYPE(IOKIT_SPARE); + PRINT_ONE_PORT_TYPE(NAMED_ENTRY); + PRINT_ONE_PORT_TYPE(IOKIT_CONNECT); + PRINT_ONE_PORT_TYPE(IOKIT_OBJECT); + PRINT_ONE_PORT_TYPE(UPL); + PRINT_ONE_PORT_TYPE(MEM_OBJ_CONTROL); + PRINT_ONE_PORT_TYPE(UNKNOWN); printf("\nipc_space:\n\n"); printf("NULL KERNEL REPLY PAGER OTHER\n"); @@ -1588,10 +1557,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( @@ -1626,7 +1595,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); @@ -1687,7 +1656,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]; @@ -1699,7 +1668,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); @@ -1714,7 +1683,7 @@ void port_callers_print( void port_track_init( port_track *trackp, - char *name) + const char *name) { port_item *i; @@ -1836,7 +1805,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; @@ -1854,7 +1822,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))