2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
29 * Mach Operating System
30 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
31 * All Rights Reserved.
33 * Permission to use, copy, modify and distribute this software and its
34 * documentation is hereby granted, provided that both the copyright
35 * notice and this permission notice appear in all copies of the
36 * software, derivative works or modified versions, and any portions
37 * thereof, and that both notices appear in supporting documentation.
39 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
40 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
41 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
43 * Carnegie Mellon requests users of this software to return to
45 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
46 * School of Computer Science
47 * Carnegie Mellon University
48 * Pittsburgh PA 15213-3890
50 * any improvements or extensions that they make and grant Carnegie Mellon
51 * the rights to redistribute these changes.
56 #include <mach/boolean.h>
57 #include <mach/thread_switch.h>
58 #include <ipc/ipc_port.h>
59 #include <ipc/ipc_space.h>
60 #include <kern/counters.h>
61 #include <kern/etap_macros.h>
62 #include <kern/ipc_kobject.h>
63 #include <kern/processor.h>
64 #include <kern/sched.h>
65 #include <kern/sched_prim.h>
67 #include <kern/task.h>
68 #include <kern/thread.h>
70 #include <mach/policy.h>
72 #include <kern/syscall_subr.h>
73 #include <mach/mach_host_server.h>
74 #include <mach/mach_syscalls.h>
76 #include <kern/mk_sp.h>
79 * swtch and swtch_pri both attempt to context switch (logic in
80 * thread_block no-ops the context switch if nothing would happen).
81 * A boolean is returned that indicates whether there is anything
84 * This boolean can be used by a thread waiting on a
85 * lock or condition: If FALSE is returned, the thread is justified
86 * in becoming a resource hog by continuing to spin because there's
87 * nothing else useful that the processor could do. If TRUE is
88 * returned, the thread should make one more check on the
89 * lock and then be a good citizen and really suspend.
95 register processor_t myprocessor
;
98 mp_disable_preemption();
99 myprocessor
= current_processor();
100 result
= myprocessor
->runq
.count
> 0 ||
101 myprocessor
->processor_set
->runq
.count
> 0;
102 mp_enable_preemption();
104 thread_syscall_return(result
);
111 register processor_t myprocessor
;
114 mp_disable_preemption();
115 myprocessor
= current_processor();
116 if ( myprocessor
->runq
.count
== 0 &&
117 myprocessor
->processor_set
->runq
.count
== 0 ) {
118 mp_enable_preemption();
122 mp_enable_preemption();
124 counter(c_swtch_block
++);
126 thread_block_reason(swtch_continue
, AST_YIELD
);
128 mp_disable_preemption();
129 myprocessor
= current_processor();
130 result
= myprocessor
->runq
.count
> 0 ||
131 myprocessor
->processor_set
->runq
.count
> 0;
132 mp_enable_preemption();
138 swtch_pri_continue(void)
140 register processor_t myprocessor
;
143 _mk_sp_thread_depress_abort(current_thread(), FALSE
);
145 mp_disable_preemption();
146 myprocessor
= current_processor();
147 result
= myprocessor
->runq
.count
> 0 ||
148 myprocessor
->processor_set
->runq
.count
> 0;
149 mp_enable_preemption();
151 thread_syscall_return(result
);
159 register processor_t myprocessor
;
162 mp_disable_preemption();
163 myprocessor
= current_processor();
164 if ( myprocessor
->runq
.count
== 0 &&
165 myprocessor
->processor_set
->runq
.count
== 0 ) {
166 mp_enable_preemption();
170 mp_enable_preemption();
172 counter(c_swtch_pri_block
++);
174 _mk_sp_thread_depress_abstime(std_quantum
);
176 thread_block_reason(swtch_pri_continue
, AST_YIELD
);
178 _mk_sp_thread_depress_abort(current_thread(), FALSE
);
180 mp_disable_preemption();
181 myprocessor
= current_processor();
182 result
= myprocessor
->runq
.count
> 0 ||
183 myprocessor
->processor_set
->runq
.count
> 0;
184 mp_enable_preemption();
192 * Context switch. User may supply thread hint.
196 mach_port_name_t thread_name
,
198 mach_msg_timeout_t option_time
)
200 register thread_t self
= current_thread();
201 register thread_act_t hint_act
= THR_ACT_NULL
;
208 case SWITCH_OPTION_NONE
:
209 case SWITCH_OPTION_DEPRESS
:
210 case SWITCH_OPTION_WAIT
:
214 return (KERN_INVALID_ARGUMENT
);
217 if (thread_name
!= MACH_PORT_NULL
) {
220 if (ipc_port_translate_send(self
->top_act
->task
->itk_space
,
221 thread_name
, &port
) == KERN_SUCCESS
) {
225 hint_act
= convert_port_to_act(port
);
226 ipc_port_release(port
);
230 return _mk_sp_thread_switch(hint_act
, option
, option_time
);