2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
23 #include <mach/mach_types.h>
24 #include <mach/thread_act_server.h>
26 #include <kern/kern_types.h>
27 #include <kern/processor.h>
28 #include <kern/thread.h>
31 thread_recompute_priority(
37 thread_policy_flavor_t flavor
,
38 thread_policy_t policy_info
,
39 mach_msg_type_number_t count
)
41 kern_return_t result
= KERN_SUCCESS
;
44 if (thread
== THREAD_NULL
)
45 return (KERN_INVALID_ARGUMENT
);
47 thread_mtx_lock(thread
);
48 if (!thread
->active
) {
49 thread_mtx_unlock(thread
);
51 return (KERN_TERMINATED
);
56 case THREAD_EXTENDED_POLICY
:
58 boolean_t timeshare
= TRUE
;
60 if (count
>= THREAD_EXTENDED_POLICY_COUNT
) {
61 thread_extended_policy_t info
;
63 info
= (thread_extended_policy_t
)policy_info
;
64 timeshare
= info
->timeshare
;
70 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
71 integer_t oldmode
= (thread
->sched_mode
& TH_MODE_TIMESHARE
);
73 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
75 if (timeshare
&& !oldmode
) {
76 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
78 if (thread
->state
& TH_RUN
)
79 pset_share_incr(thread
->processor_set
);
82 if (!timeshare
&& oldmode
) {
83 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
85 if (thread
->state
& TH_RUN
)
86 pset_share_decr(thread
->processor_set
);
89 thread_recompute_priority(thread
);
92 thread
->safe_mode
&= ~TH_MODE_REALTIME
;
95 thread
->safe_mode
|= TH_MODE_TIMESHARE
;
97 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
100 thread_unlock(thread
);
106 case THREAD_TIME_CONSTRAINT_POLICY
:
108 thread_time_constraint_policy_t info
;
110 if (count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
111 result
= KERN_INVALID_ARGUMENT
;
115 info
= (thread_time_constraint_policy_t
)policy_info
;
116 if ( info
->constraint
< info
->computation
||
117 info
->computation
> max_rt_quantum
||
118 info
->computation
< min_rt_quantum
) {
119 result
= KERN_INVALID_ARGUMENT
;
126 thread
->realtime
.period
= info
->period
;
127 thread
->realtime
.computation
= info
->computation
;
128 thread
->realtime
.constraint
= info
->constraint
;
129 thread
->realtime
.preemptible
= info
->preemptible
;
131 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
132 if (thread
->sched_mode
& TH_MODE_TIMESHARE
) {
133 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
135 if (thread
->state
& TH_RUN
)
136 pset_share_decr(thread
->processor_set
);
138 thread
->sched_mode
|= TH_MODE_REALTIME
;
139 thread_recompute_priority(thread
);
142 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
143 thread
->safe_mode
|= TH_MODE_REALTIME
;
146 thread_unlock(thread
);
152 case THREAD_PRECEDENCE_POLICY
:
154 thread_precedence_policy_t info
;
156 if (count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
157 result
= KERN_INVALID_ARGUMENT
;
161 info
= (thread_precedence_policy_t
)policy_info
;
166 thread
->importance
= info
->importance
;
168 thread_recompute_priority(thread
);
170 thread_unlock(thread
);
177 result
= KERN_INVALID_ARGUMENT
;
181 thread_mtx_unlock(thread
);
187 thread_recompute_priority(
192 if (thread
->sched_mode
& TH_MODE_REALTIME
)
193 priority
= BASEPRI_RTQUEUES
;
195 if (thread
->importance
> MAXPRI
)
198 if (thread
->importance
< -MAXPRI
)
201 priority
= thread
->importance
;
203 priority
+= thread
->task_priority
;
205 if (priority
> thread
->max_priority
)
206 priority
= thread
->max_priority
;
208 if (priority
< MINPRI
)
212 set_priority(thread
, priority
);
216 thread_task_priority(
219 integer_t max_priority
)
223 assert(thread
!= THREAD_NULL
);
228 thread
->task_priority
= priority
;
229 thread
->max_priority
= max_priority
;
231 thread_recompute_priority(thread
);
233 thread_unlock(thread
);
241 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
242 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
244 if (!(thread
->sched_mode
& TH_MODE_TIMESHARE
)) {
245 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
247 if (thread
->state
& TH_RUN
)
248 pset_share_incr(thread
->processor_set
);
252 thread
->safe_mode
= 0;
253 thread
->sched_mode
&= ~TH_MODE_FAILSAFE
;
256 thread
->importance
= 0;
258 thread_recompute_priority(thread
);
264 thread_policy_flavor_t flavor
,
265 thread_policy_t policy_info
,
266 mach_msg_type_number_t
*count
,
267 boolean_t
*get_default
)
269 kern_return_t result
= KERN_SUCCESS
;
272 if (thread
== THREAD_NULL
)
273 return (KERN_INVALID_ARGUMENT
);
275 thread_mtx_lock(thread
);
276 if (!thread
->active
) {
277 thread_mtx_unlock(thread
);
279 return (KERN_TERMINATED
);
284 case THREAD_EXTENDED_POLICY
:
286 boolean_t timeshare
= TRUE
;
288 if (!(*get_default
)) {
292 if ( !(thread
->sched_mode
& TH_MODE_REALTIME
) &&
293 !(thread
->safe_mode
& TH_MODE_REALTIME
) ) {
294 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
))
295 timeshare
= (thread
->sched_mode
& TH_MODE_TIMESHARE
) != 0;
297 timeshare
= (thread
->safe_mode
& TH_MODE_TIMESHARE
) != 0;
302 thread_unlock(thread
);
306 if (*count
>= THREAD_EXTENDED_POLICY_COUNT
) {
307 thread_extended_policy_t info
;
309 info
= (thread_extended_policy_t
)policy_info
;
310 info
->timeshare
= timeshare
;
316 case THREAD_TIME_CONSTRAINT_POLICY
:
318 thread_time_constraint_policy_t info
;
320 if (*count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
321 result
= KERN_INVALID_ARGUMENT
;
325 info
= (thread_time_constraint_policy_t
)policy_info
;
327 if (!(*get_default
)) {
331 if ( (thread
->sched_mode
& TH_MODE_REALTIME
) ||
332 (thread
->safe_mode
& TH_MODE_REALTIME
) ) {
333 info
->period
= thread
->realtime
.period
;
334 info
->computation
= thread
->realtime
.computation
;
335 info
->constraint
= thread
->realtime
.constraint
;
336 info
->preemptible
= thread
->realtime
.preemptible
;
341 thread_unlock(thread
);
347 info
->computation
= std_quantum
/ 2;
348 info
->constraint
= std_quantum
;
349 info
->preemptible
= TRUE
;
355 case THREAD_PRECEDENCE_POLICY
:
357 thread_precedence_policy_t info
;
359 if (*count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
360 result
= KERN_INVALID_ARGUMENT
;
364 info
= (thread_precedence_policy_t
)policy_info
;
366 if (!(*get_default
)) {
370 info
->importance
= thread
->importance
;
372 thread_unlock(thread
);
376 info
->importance
= 0;
382 result
= KERN_INVALID_ARGUMENT
;
386 thread_mtx_unlock(thread
);