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@
26 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
30 * 15 October 2000 (debo)
34 #include <kern/processor.h>
35 #include <kern/thread.h>
38 thread_recompute_priority(
44 thread_policy_flavor_t flavor
,
45 thread_policy_t policy_info
,
46 mach_msg_type_number_t count
)
48 kern_return_t result
= KERN_SUCCESS
;
52 if (act
== THR_ACT_NULL
)
53 return (KERN_INVALID_ARGUMENT
);
55 thread
= act_lock_thread(act
);
57 act_unlock_thread(act
);
59 return (KERN_TERMINATED
);
62 assert(thread
!= THREAD_NULL
);
66 case THREAD_EXTENDED_POLICY
:
68 boolean_t timeshare
= TRUE
;
70 if (count
>= THREAD_EXTENDED_POLICY_COUNT
) {
71 thread_extended_policy_t info
;
73 info
= (thread_extended_policy_t
)policy_info
;
74 timeshare
= info
->timeshare
;
80 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
81 integer_t oldmode
= (thread
->sched_mode
& TH_MODE_TIMESHARE
);
83 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
85 if (timeshare
&& !oldmode
) {
86 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
88 if (thread
->state
& TH_RUN
)
89 pset_share_incr(thread
->processor_set
);
92 if (!timeshare
&& oldmode
) {
93 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
95 if (thread
->state
& TH_RUN
)
96 pset_share_decr(thread
->processor_set
);
99 thread_recompute_priority(thread
);
102 thread
->safe_mode
&= ~TH_MODE_REALTIME
;
105 thread
->safe_mode
|= TH_MODE_TIMESHARE
;
107 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
110 thread_unlock(thread
);
116 case THREAD_TIME_CONSTRAINT_POLICY
:
118 thread_time_constraint_policy_t info
;
120 if (count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
121 result
= KERN_INVALID_ARGUMENT
;
125 info
= (thread_time_constraint_policy_t
)policy_info
;
126 if ( info
->constraint
< info
->computation
||
127 info
->computation
> max_rt_quantum
||
128 info
->computation
< min_rt_quantum
) {
129 result
= KERN_INVALID_ARGUMENT
;
136 thread
->realtime
.period
= info
->period
;
137 thread
->realtime
.computation
= info
->computation
;
138 thread
->realtime
.constraint
= info
->constraint
;
139 thread
->realtime
.preemptible
= info
->preemptible
;
141 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
142 if (thread
->sched_mode
& TH_MODE_TIMESHARE
) {
143 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
145 if (thread
->state
& TH_RUN
)
146 pset_share_decr(thread
->processor_set
);
148 thread
->sched_mode
|= TH_MODE_REALTIME
;
149 thread_recompute_priority(thread
);
152 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
153 thread
->safe_mode
|= TH_MODE_REALTIME
;
156 thread_unlock(thread
);
162 case THREAD_PRECEDENCE_POLICY
:
164 thread_precedence_policy_t info
;
166 if (count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
167 result
= KERN_INVALID_ARGUMENT
;
171 info
= (thread_precedence_policy_t
)policy_info
;
176 thread
->importance
= info
->importance
;
178 thread_recompute_priority(thread
);
180 thread_unlock(thread
);
187 result
= KERN_INVALID_ARGUMENT
;
191 act_unlock_thread(act
);
197 thread_recompute_priority(
202 if (thread
->sched_mode
& TH_MODE_REALTIME
)
203 priority
= BASEPRI_RTQUEUES
;
205 if (thread
->importance
> MAXPRI
)
208 if (thread
->importance
< -MAXPRI
)
211 priority
= thread
->importance
;
213 priority
+= thread
->task_priority
;
215 if (priority
> thread
->max_priority
)
216 priority
= thread
->max_priority
;
218 if (priority
< MINPRI
)
222 set_priority(thread
, priority
);
226 thread_task_priority(
229 integer_t max_priority
)
233 assert(thread
!= THREAD_NULL
);
238 thread
->task_priority
= priority
;
239 thread
->max_priority
= max_priority
;
241 thread_recompute_priority(thread
);
243 thread_unlock(thread
);
250 thread_policy_flavor_t flavor
,
251 thread_policy_t policy_info
,
252 mach_msg_type_number_t
*count
,
253 boolean_t
*get_default
)
255 kern_return_t result
= KERN_SUCCESS
;
259 if (act
== THR_ACT_NULL
)
260 return (KERN_INVALID_ARGUMENT
);
262 thread
= act_lock_thread(act
);
264 act_unlock_thread(act
);
266 return (KERN_TERMINATED
);
269 assert(thread
!= THREAD_NULL
);
273 case THREAD_EXTENDED_POLICY
:
275 boolean_t timeshare
= TRUE
;
277 if (!(*get_default
)) {
281 if ( !(thread
->sched_mode
& TH_MODE_REALTIME
) &&
282 !(thread
->safe_mode
& TH_MODE_REALTIME
) ) {
283 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
))
284 timeshare
= (thread
->sched_mode
& TH_MODE_TIMESHARE
) != 0;
286 timeshare
= (thread
->safe_mode
& TH_MODE_TIMESHARE
) != 0;
291 thread_unlock(thread
);
295 if (*count
>= THREAD_EXTENDED_POLICY_COUNT
) {
296 thread_extended_policy_t info
;
298 info
= (thread_extended_policy_t
)policy_info
;
299 info
->timeshare
= timeshare
;
305 case THREAD_TIME_CONSTRAINT_POLICY
:
307 thread_time_constraint_policy_t info
;
309 if (*count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
310 result
= KERN_INVALID_ARGUMENT
;
314 info
= (thread_time_constraint_policy_t
)policy_info
;
316 if (!(*get_default
)) {
320 if ( (thread
->sched_mode
& TH_MODE_REALTIME
) ||
321 (thread
->safe_mode
& TH_MODE_REALTIME
) ) {
322 info
->period
= thread
->realtime
.period
;
323 info
->computation
= thread
->realtime
.computation
;
324 info
->constraint
= thread
->realtime
.constraint
;
325 info
->preemptible
= thread
->realtime
.preemptible
;
330 thread_unlock(thread
);
336 info
->computation
= std_quantum
/ 2;
337 info
->constraint
= std_quantum
;
338 info
->preemptible
= TRUE
;
344 case THREAD_PRECEDENCE_POLICY
:
346 thread_precedence_policy_t info
;
348 if (*count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
349 result
= KERN_INVALID_ARGUMENT
;
353 info
= (thread_precedence_policy_t
)policy_info
;
355 if (!(*get_default
)) {
359 info
->importance
= thread
->importance
;
361 thread_unlock(thread
);
365 info
->importance
= 0;
371 result
= KERN_INVALID_ARGUMENT
;
375 act_unlock_thread(act
);