2 * Copyright (c) 2000 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 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
27 * 15 October 2000 (debo)
31 #include <kern/thread.h>
34 thread_recompute_priority(
40 thread_policy_flavor_t flavor
,
41 thread_policy_t policy_info
,
42 mach_msg_type_number_t count
)
44 kern_return_t result
= KERN_SUCCESS
;
48 if (act
== THR_ACT_NULL
)
49 return (KERN_INVALID_ARGUMENT
);
51 thread
= act_lock_thread(act
);
53 act_unlock_thread(act
);
55 return (KERN_TERMINATED
);
58 assert(thread
!= THREAD_NULL
);
62 case THREAD_EXTENDED_POLICY
:
64 boolean_t timeshare
= TRUE
;
66 if (count
>= THREAD_EXTENDED_POLICY_COUNT
) {
67 thread_extended_policy_t info
;
69 info
= (thread_extended_policy_t
)policy_info
;
70 timeshare
= info
->timeshare
;
76 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
77 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
80 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
82 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
84 thread_recompute_priority(thread
);
87 thread
->safe_mode
&= ~TH_MODE_REALTIME
;
90 thread
->safe_mode
|= TH_MODE_TIMESHARE
;
92 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
95 thread_unlock(thread
);
101 case THREAD_TIME_CONSTRAINT_POLICY
:
103 thread_time_constraint_policy_t info
;
105 if (count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
106 result
= KERN_INVALID_ARGUMENT
;
110 info
= (thread_time_constraint_policy_t
)policy_info
;
111 if ( info
->computation
> max_rt_quantum
||
112 info
->computation
< min_rt_quantum
) {
113 result
= KERN_INVALID_ARGUMENT
;
120 thread
->realtime
.period
= info
->period
;
121 thread
->realtime
.computation
= info
->computation
;
122 thread
->realtime
.constraint
= info
->constraint
;
123 thread
->realtime
.preemptible
= info
->preemptible
;
125 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
126 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
127 thread
->sched_mode
|= TH_MODE_REALTIME
;
128 thread_recompute_priority(thread
);
131 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
132 thread
->safe_mode
|= TH_MODE_REALTIME
;
135 thread_unlock(thread
);
141 case THREAD_PRECEDENCE_POLICY
:
143 thread_precedence_policy_t info
;
145 if (count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
146 result
= KERN_INVALID_ARGUMENT
;
150 info
= (thread_precedence_policy_t
)policy_info
;
155 thread
->importance
= info
->importance
;
157 thread_recompute_priority(thread
);
159 thread_unlock(thread
);
166 result
= KERN_INVALID_ARGUMENT
;
170 act_unlock_thread(act
);
176 thread_recompute_priority(
181 if (thread
->sched_mode
& TH_MODE_REALTIME
)
182 priority
= BASEPRI_REALTIME
;
184 if (thread
->importance
> MAXPRI
)
187 if (thread
->importance
< -MAXPRI
)
190 priority
= thread
->importance
;
192 priority
+= thread
->task_priority
;
194 if (priority
> thread
->max_priority
)
195 priority
= thread
->max_priority
;
197 if (priority
< MINPRI
)
201 if (thread
->depress_priority
>= 0)
202 thread
->depress_priority
= priority
;
204 thread
->priority
= priority
;
205 compute_priority(thread
, TRUE
);
207 if (thread
== current_thread())
213 thread_task_priority(
216 integer_t max_priority
)
220 assert(thread
!= THREAD_NULL
);
225 thread
->task_priority
= priority
;
226 thread
->max_priority
= max_priority
;
228 thread_recompute_priority(thread
);
230 thread_unlock(thread
);
237 thread_policy_flavor_t flavor
,
238 thread_policy_t policy_info
,
239 mach_msg_type_number_t
*count
,
240 boolean_t
*get_default
)
242 kern_return_t result
= KERN_SUCCESS
;
246 if (act
== THR_ACT_NULL
)
247 return (KERN_INVALID_ARGUMENT
);
249 thread
= act_lock_thread(act
);
251 act_unlock_thread(act
);
253 return (KERN_TERMINATED
);
256 assert(thread
!= THREAD_NULL
);
260 case THREAD_EXTENDED_POLICY
:
262 boolean_t timeshare
= TRUE
;
264 if (!(*get_default
)) {
268 if ( !(thread
->sched_mode
& TH_MODE_REALTIME
) &&
269 !(thread
->safe_mode
& TH_MODE_REALTIME
) ) {
270 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
))
271 timeshare
= (thread
->sched_mode
& TH_MODE_TIMESHARE
) != 0;
273 timeshare
= (thread
->safe_mode
& TH_MODE_TIMESHARE
) != 0;
278 thread_unlock(thread
);
282 if (*count
>= THREAD_EXTENDED_POLICY_COUNT
) {
283 thread_extended_policy_t info
;
285 info
= (thread_extended_policy_t
)policy_info
;
286 info
->timeshare
= timeshare
;
292 case THREAD_TIME_CONSTRAINT_POLICY
:
294 thread_time_constraint_policy_t info
;
296 if (*count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
297 result
= KERN_INVALID_ARGUMENT
;
301 info
= (thread_time_constraint_policy_t
)policy_info
;
303 if (!(*get_default
)) {
307 if ( (thread
->sched_mode
& TH_MODE_REALTIME
) ||
308 (thread
->safe_mode
& TH_MODE_REALTIME
) ) {
309 info
->period
= thread
->realtime
.period
;
310 info
->computation
= thread
->realtime
.computation
;
311 info
->constraint
= thread
->realtime
.constraint
;
312 info
->preemptible
= thread
->realtime
.preemptible
;
317 thread_unlock(thread
);
323 info
->computation
= std_quantum
/ 2;
324 info
->constraint
= std_quantum
;
325 info
->preemptible
= TRUE
;
331 case THREAD_PRECEDENCE_POLICY
:
333 thread_precedence_policy_t info
;
335 if (*count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
336 result
= KERN_INVALID_ARGUMENT
;
340 info
= (thread_precedence_policy_t
)policy_info
;
342 if (!(*get_default
)) {
346 info
->importance
= thread
->importance
;
348 thread_unlock(thread
);
352 info
->importance
= 0;
358 result
= KERN_INVALID_ARGUMENT
;
362 act_unlock_thread(act
);