2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <mach/mach_types.h>
25 #include <mach/thread_act_server.h>
27 #include <kern/kern_types.h>
28 #include <kern/processor.h>
29 #include <kern/thread.h>
32 thread_recompute_priority(
38 thread_policy_flavor_t flavor
,
39 thread_policy_t policy_info
,
40 mach_msg_type_number_t count
)
42 kern_return_t result
= KERN_SUCCESS
;
45 if (thread
== THREAD_NULL
)
46 return (KERN_INVALID_ARGUMENT
);
48 thread_mtx_lock(thread
);
49 if (!thread
->active
) {
50 thread_mtx_unlock(thread
);
52 return (KERN_TERMINATED
);
57 case THREAD_EXTENDED_POLICY
:
59 boolean_t timeshare
= TRUE
;
61 if (count
>= THREAD_EXTENDED_POLICY_COUNT
) {
62 thread_extended_policy_t info
;
64 info
= (thread_extended_policy_t
)policy_info
;
65 timeshare
= info
->timeshare
;
71 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
72 integer_t oldmode
= (thread
->sched_mode
& TH_MODE_TIMESHARE
);
74 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
76 if (timeshare
&& !oldmode
) {
77 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
79 if (thread
->state
& TH_RUN
)
80 pset_share_incr(thread
->processor_set
);
83 if (!timeshare
&& oldmode
) {
84 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
86 if (thread
->state
& TH_RUN
)
87 pset_share_decr(thread
->processor_set
);
90 thread_recompute_priority(thread
);
93 thread
->safe_mode
&= ~TH_MODE_REALTIME
;
96 thread
->safe_mode
|= TH_MODE_TIMESHARE
;
98 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
101 thread_unlock(thread
);
107 case THREAD_TIME_CONSTRAINT_POLICY
:
109 thread_time_constraint_policy_t info
;
111 if (count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
112 result
= KERN_INVALID_ARGUMENT
;
116 info
= (thread_time_constraint_policy_t
)policy_info
;
117 if ( info
->constraint
< info
->computation
||
118 info
->computation
> max_rt_quantum
||
119 info
->computation
< min_rt_quantum
) {
120 result
= KERN_INVALID_ARGUMENT
;
127 thread
->realtime
.period
= info
->period
;
128 thread
->realtime
.computation
= info
->computation
;
129 thread
->realtime
.constraint
= info
->constraint
;
130 thread
->realtime
.preemptible
= info
->preemptible
;
132 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
133 if (thread
->sched_mode
& TH_MODE_TIMESHARE
) {
134 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
136 if (thread
->state
& TH_RUN
)
137 pset_share_decr(thread
->processor_set
);
139 thread
->sched_mode
|= TH_MODE_REALTIME
;
140 thread_recompute_priority(thread
);
143 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
144 thread
->safe_mode
|= TH_MODE_REALTIME
;
147 thread_unlock(thread
);
153 case THREAD_PRECEDENCE_POLICY
:
155 thread_precedence_policy_t info
;
157 if (count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
158 result
= KERN_INVALID_ARGUMENT
;
162 info
= (thread_precedence_policy_t
)policy_info
;
167 thread
->importance
= info
->importance
;
169 thread_recompute_priority(thread
);
171 thread_unlock(thread
);
178 result
= KERN_INVALID_ARGUMENT
;
182 thread_mtx_unlock(thread
);
188 thread_recompute_priority(
193 if (thread
->sched_mode
& TH_MODE_REALTIME
)
194 priority
= BASEPRI_RTQUEUES
;
196 if (thread
->importance
> MAXPRI
)
199 if (thread
->importance
< -MAXPRI
)
202 priority
= thread
->importance
;
204 priority
+= thread
->task_priority
;
206 if (priority
> thread
->max_priority
)
207 priority
= thread
->max_priority
;
209 if (priority
< MINPRI
)
213 set_priority(thread
, priority
);
217 thread_task_priority(
220 integer_t max_priority
)
224 assert(thread
!= THREAD_NULL
);
229 thread
->task_priority
= priority
;
230 thread
->max_priority
= max_priority
;
232 thread_recompute_priority(thread
);
234 thread_unlock(thread
);
242 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
243 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
245 if (!(thread
->sched_mode
& TH_MODE_TIMESHARE
)) {
246 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
248 if (thread
->state
& TH_RUN
)
249 pset_share_incr(thread
->processor_set
);
253 thread
->safe_mode
= 0;
254 thread
->sched_mode
&= ~TH_MODE_FAILSAFE
;
257 thread
->importance
= 0;
259 thread_recompute_priority(thread
);
265 thread_policy_flavor_t flavor
,
266 thread_policy_t policy_info
,
267 mach_msg_type_number_t
*count
,
268 boolean_t
*get_default
)
270 kern_return_t result
= KERN_SUCCESS
;
273 if (thread
== THREAD_NULL
)
274 return (KERN_INVALID_ARGUMENT
);
276 thread_mtx_lock(thread
);
277 if (!thread
->active
) {
278 thread_mtx_unlock(thread
);
280 return (KERN_TERMINATED
);
285 case THREAD_EXTENDED_POLICY
:
287 boolean_t timeshare
= TRUE
;
289 if (!(*get_default
)) {
293 if ( !(thread
->sched_mode
& TH_MODE_REALTIME
) &&
294 !(thread
->safe_mode
& TH_MODE_REALTIME
) ) {
295 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
))
296 timeshare
= (thread
->sched_mode
& TH_MODE_TIMESHARE
) != 0;
298 timeshare
= (thread
->safe_mode
& TH_MODE_TIMESHARE
) != 0;
303 thread_unlock(thread
);
307 if (*count
>= THREAD_EXTENDED_POLICY_COUNT
) {
308 thread_extended_policy_t info
;
310 info
= (thread_extended_policy_t
)policy_info
;
311 info
->timeshare
= timeshare
;
317 case THREAD_TIME_CONSTRAINT_POLICY
:
319 thread_time_constraint_policy_t info
;
321 if (*count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
322 result
= KERN_INVALID_ARGUMENT
;
326 info
= (thread_time_constraint_policy_t
)policy_info
;
328 if (!(*get_default
)) {
332 if ( (thread
->sched_mode
& TH_MODE_REALTIME
) ||
333 (thread
->safe_mode
& TH_MODE_REALTIME
) ) {
334 info
->period
= thread
->realtime
.period
;
335 info
->computation
= thread
->realtime
.computation
;
336 info
->constraint
= thread
->realtime
.constraint
;
337 info
->preemptible
= thread
->realtime
.preemptible
;
342 thread_unlock(thread
);
348 info
->computation
= std_quantum
/ 2;
349 info
->constraint
= std_quantum
;
350 info
->preemptible
= TRUE
;
356 case THREAD_PRECEDENCE_POLICY
:
358 thread_precedence_policy_t info
;
360 if (*count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
361 result
= KERN_INVALID_ARGUMENT
;
365 info
= (thread_precedence_policy_t
)policy_info
;
367 if (!(*get_default
)) {
371 info
->importance
= thread
->importance
;
373 thread_unlock(thread
);
377 info
->importance
= 0;
383 result
= KERN_INVALID_ARGUMENT
;
387 thread_mtx_unlock(thread
);