*
* @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.
+ * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * 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.
+ *
+ * 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@
*/
mach_port_seqno_t seqno,
ipc_space_t space);
-/* the size of each trailer has to be listed here for copyout purposes */
-mach_msg_trailer_size_t trailer_size[] = {
- sizeof(mach_msg_trailer_t),
- sizeof(mach_msg_seqno_trailer_t),
- sizeof(mach_msg_security_trailer_t) };
-
security_token_t KERNEL_SECURITY_TOKEN = KERNEL_SECURITY_TOKEN_VALUE;
mach_msg_format_0_trailer_t trailer_template = {
assert(ip_active(dest_port));
assert(dest_port->ip_receiver != ipc_space_kernel);
- assert(!imq_full(&dest_port->ip_messages) ||
- (MACH_MSGH_BITS_REMOTE(hdr->msgh_bits) ==
- MACH_MSG_TYPE_PORT_SEND_ONCE));
+// assert(!imq_full(&dest_port->ip_messages) ||
+// (MACH_MSGH_BITS_REMOTE(hdr->msgh_bits) ==
+// MACH_MSG_TYPE_PORT_SEND_ONCE));
assert((hdr->msgh_bits & MACH_MSGH_BITS_CIRCULAR) == 0);
{
waitq = &dest_mqueue->imq_wait_queue;
imq_lock(dest_mqueue);
- wait_queue_peek_locked(waitq, IPC_MQUEUE_RECEIVE, &receiver, &waitq);
+ wait_queue_peek64_locked(waitq, IPC_MQUEUE_RECEIVE, &receiver, &waitq);
/* queue still locked, thread locked - but still on q */
if (receiver == THREAD_NULL) {
* slow receive for ourselves. Only his RECEIVE_TOO_LARGE handling
* runs afoul of that. Clean this up!
*/
- if ((receiver->state & TH_RUN|TH_WAIT) != TH_WAIT) {
+ if ((receiver->state & (TH_RUN|TH_WAIT)) != TH_WAIT) {
assert(NCPUS > 1);
HOT(c_mmot_cold_033++);
fall_off:
/*
* Receiver looks okay -- is it swapped in?
*/
- rpc_lock(receiver);
rcv_act = receiver->top_act;
if (rcv_act->swap_state != TH_SW_IN &&
rcv_act->swap_state != TH_SW_UNSWAPPABLE) {
- rpc_unlock(receiver);
HOT(c_mmot_rcvr_swapped++);
goto fall_off;
}
* Make sure receiver stays swapped in (if we can).
*/
if (!act_lock_try(rcv_act)) { /* out of order! */
- rpc_unlock(receiver);
HOT(c_mmot_rcvr_locked++);
goto fall_off;
}
rcv_act->swap_state != TH_SW_UNSWAPPABLE) ||
rcv_act->ast & AST_SWAPOUT) {
act_unlock(rcv_act);
- rpc_unlock(receiver);
HOT(c_mmot_rcvr_tswapped++);
goto fall_off;
}
* is consistent. Its task may then be marked for swapout,
* but that's life.
*/
- rpc_unlock(receiver);
/*
* NB: act_lock(rcv_act) still held
*/
*/
{
receiver->state &= ~(TH_WAIT|TH_UNINT);
+ hw_atomic_add(&receiver->processor_set->run_count, 1);
receiver->state |= TH_RUN;
receiver->wait_result = THREAD_AWAKENED;
- receiver->metered_computation = 0;
+ receiver->computation_metered = 0;
+ receiver->reason = AST_NONE;
}
thread_unlock(receiver);
self->ith_continuation = thread_syscall_return;
waitq = &rcv_mqueue->imq_wait_queue;
- (void)wait_queue_assert_wait_locked(waitq,
+ (void)wait_queue_assert_wait64_locked(waitq,
IPC_MQUEUE_RECEIVE,
THREAD_ABORTSAFE,
TRUE); /* unlock? */
/* rcv_mqueue is unlocked */
- /* Inline thread_block_reason (except don't select a new
- * new thread (we already have one), and don't turn off ASTs
- * (we don't want two threads to hog all the CPU by handing
- * off to each other).
+ /*
+ * Switch directly to receiving thread, and block
+ * this thread as though it had called ipc_mqueue_receive.
*/
- {
- if (self->funnel_state & TH_FN_OWNED) {
- self->funnel_state = TH_FN_REFUNNEL;
- KERNEL_DEBUG(0x603242c | DBG_FUNC_NONE, self->funnel_lock, 3, 0, 0, 0);
- funnel_unlock(self->funnel_lock);
-
- }
-
- machine_clock_assist();
-
- thread_lock(self);
- if (self->state & TH_ABORT)
- clear_wait_internal(self, THREAD_INTERRUPTED);
- thread_unlock(self);
-
- /*
- * Switch directly to receiving thread, and block
- * this thread as though it had called ipc_mqueue_receive.
- */
-#if defined (__i386__)
- thread_run(self, (void (*)(void))0, receiver);
-#else
- thread_run(self, ipc_mqueue_receive_continue, receiver);
-#endif
-
- /* if we fell thru */
- if (self->funnel_state & TH_FN_REFUNNEL) {
- kern_return_t wait_result2;
-
- wait_result2 = self->wait_result;
- self->funnel_state = 0;
- KERNEL_DEBUG(0x6032428 | DBG_FUNC_NONE, self->funnel_lock, 6, 0, 0, 0);
- funnel_lock(self->funnel_lock);
- KERNEL_DEBUG(0x6032430 | DBG_FUNC_NONE, self->funnel_lock, 6, 0, 0, 0);
- self->funnel_state = TH_FN_OWNED;
- self->wait_result = wait_result2;
- }
- splx(s);
- }
-
- ipc_mqueue_receive_continue();
+ thread_run(self, ipc_mqueue_receive_continue, receiver);
/* NOTREACHED */
}
return MACH_MSG_SUCCESS;
}
+/*
+ * Routine: mach_msg_trap [mach trap]
+ * Purpose:
+ * Possibly send a message; possibly receive a message.
+ * Conditions:
+ * Nothing locked.
+ * Returns:
+ * All of mach_msg_send and mach_msg_receive error codes.
+ */
+
+mach_msg_return_t
+mach_msg_trap(
+ mach_msg_header_t *msg,
+ mach_msg_option_t option,
+ mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size,
+ mach_port_name_t rcv_name,
+ mach_msg_timeout_t timeout,
+ mach_port_name_t notify)
+{
+ return mach_msg_overwrite_trap(msg,
+ option,
+ send_size,
+ rcv_size,
+ rcv_name,
+ timeout,
+ notify,
+ (mach_msg_header_t *)0,
+ (mach_msg_size_t)0);
+}
+
+
/*
* Routine: msg_receive_error [internal]
* Purpose: