]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/syscall_subr.c
xnu-517.3.15.tar.gz
[apple/xnu.git] / osfmk / kern / syscall_subr.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
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
13 * file.
14 *
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
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
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.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * @OSF_COPYRIGHT@
27 */
28/*
29 * Mach Operating System
30 * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
31 * All Rights Reserved.
32 *
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.
38 *
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.
42 *
43 * Carnegie Mellon requests users of this software to return to
44 *
45 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
46 * School of Computer Science
47 * Carnegie Mellon University
48 * Pittsburgh PA 15213-3890
49 *
50 * any improvements or extensions that they make and grant Carnegie Mellon
51 * the rights to redistribute these changes.
52 */
53/*
54 */
55
1c79356b
A
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>
66#include <kern/spl.h>
67#include <kern/task.h>
68#include <kern/thread.h>
69#include <kern/ast.h>
70#include <mach/policy.h>
71
72#include <kern/syscall_subr.h>
73#include <mach/mach_host_server.h>
74#include <mach/mach_syscalls.h>
75
0b4e3aa0 76#include <kern/mk_sp.h>
1c79356b
A
77
78/*
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
82 * else runnable.
83 *
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.
90 */
91
0b4e3aa0
A
92void
93swtch_continue(void)
1c79356b 94{
0b4e3aa0
A
95 register processor_t myprocessor;
96 boolean_t result;
1c79356b
A
97
98 mp_disable_preemption();
99 myprocessor = current_processor();
0b4e3aa0
A
100 result = myprocessor->runq.count > 0 ||
101 myprocessor->processor_set->runq.count > 0;
1c79356b 102 mp_enable_preemption();
1c79356b 103
0b4e3aa0
A
104 thread_syscall_return(result);
105 /*NOTREACHED*/
106}
1c79356b
A
107
108boolean_t
109swtch(void)
110{
111 register processor_t myprocessor;
112 boolean_t result;
113
114 mp_disable_preemption();
115 myprocessor = current_processor();
0b4e3aa0 116 if ( myprocessor->runq.count == 0 &&
1c79356b
A
117 myprocessor->processor_set->runq.count == 0 ) {
118 mp_enable_preemption();
119
120 return (FALSE);
121 }
122 mp_enable_preemption();
123
124 counter(c_swtch_block++);
125
9bccf70c 126 thread_block_reason(swtch_continue, AST_YIELD);
1c79356b
A
127
128 mp_disable_preemption();
129 myprocessor = current_processor();
0b4e3aa0
A
130 result = myprocessor->runq.count > 0 ||
131 myprocessor->processor_set->runq.count > 0;
1c79356b
A
132 mp_enable_preemption();
133
134 return (result);
135}
136
0b4e3aa0
A
137void
138swtch_pri_continue(void)
139{
140 register processor_t myprocessor;
141 boolean_t result;
142
143 _mk_sp_thread_depress_abort(current_thread(), FALSE);
144
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();
150
151 thread_syscall_return(result);
152 /*NOTREACHED*/
153}
154
1c79356b
A
155boolean_t
156swtch_pri(
157 int pri)
158{
1c79356b
A
159 register processor_t myprocessor;
160 boolean_t result;
1c79356b 161
0b4e3aa0 162 mp_disable_preemption();
1c79356b 163 myprocessor = current_processor();
0b4e3aa0 164 if ( myprocessor->runq.count == 0 &&
1c79356b 165 myprocessor->processor_set->runq.count == 0 ) {
0b4e3aa0 166 mp_enable_preemption();
1c79356b
A
167
168 return (FALSE);
169 }
0b4e3aa0
A
170 mp_enable_preemption();
171
172 counter(c_swtch_pri_block++);
173
174 _mk_sp_thread_depress_abstime(std_quantum);
1c79356b 175
9bccf70c 176 thread_block_reason(swtch_pri_continue, AST_YIELD);
1c79356b 177
0b4e3aa0 178 _mk_sp_thread_depress_abort(current_thread(), FALSE);
1c79356b
A
179
180 mp_disable_preemption();
181 myprocessor = current_processor();
0b4e3aa0
A
182 result = myprocessor->runq.count > 0 ||
183 myprocessor->processor_set->runq.count > 0;
1c79356b
A
184 mp_enable_preemption();
185
186 return (result);
187}
188
189/*
190 * thread_switch:
191 *
192 * Context switch. User may supply thread hint.
193 */
194kern_return_t
195thread_switch(
196 mach_port_name_t thread_name,
197 int option,
198 mach_msg_timeout_t option_time)
199{
1c79356b 200 register thread_act_t hint_act = THR_ACT_NULL;
1c79356b
A
201
202 /*
203 * Process option.
204 */
205 switch (option) {
206
207 case SWITCH_OPTION_NONE:
208 case SWITCH_OPTION_DEPRESS:
209 case SWITCH_OPTION_WAIT:
210 break;
211
212 default:
213 return (KERN_INVALID_ARGUMENT);
214 }
215
216 if (thread_name != MACH_PORT_NULL) {
217 ipc_port_t port;
218
55e303ae 219 if (ipc_port_translate_send(current_task()->itk_space,
1c79356b
A
220 thread_name, &port) == KERN_SUCCESS) {
221 ip_reference(port);
222 ip_unlock(port);
223
224 hint_act = convert_port_to_act(port);
225 ipc_port_release(port);
226 }
227 }
228
0b4e3aa0 229 return _mk_sp_thread_switch(hint_act, option, option_time);
1c79356b 230}