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/thread.h>
37 thread_recompute_priority(
43 thread_policy_flavor_t flavor
,
44 thread_policy_t policy_info
,
45 mach_msg_type_number_t count
)
47 kern_return_t result
= KERN_SUCCESS
;
51 if (act
== THR_ACT_NULL
)
52 return (KERN_INVALID_ARGUMENT
);
54 thread
= act_lock_thread(act
);
56 act_unlock_thread(act
);
58 return (KERN_TERMINATED
);
61 assert(thread
!= THREAD_NULL
);
65 case THREAD_EXTENDED_POLICY
:
67 boolean_t timeshare
= TRUE
;
69 if (count
>= THREAD_EXTENDED_POLICY_COUNT
) {
70 thread_extended_policy_t info
;
72 info
= (thread_extended_policy_t
)policy_info
;
73 timeshare
= info
->timeshare
;
79 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
80 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
83 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
85 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
87 thread_recompute_priority(thread
);
90 thread
->safe_mode
&= ~TH_MODE_REALTIME
;
93 thread
->safe_mode
|= TH_MODE_TIMESHARE
;
95 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
98 thread_unlock(thread
);
104 case THREAD_TIME_CONSTRAINT_POLICY
:
106 thread_time_constraint_policy_t info
;
108 if (count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
109 result
= KERN_INVALID_ARGUMENT
;
113 info
= (thread_time_constraint_policy_t
)policy_info
;
114 if ( info
->computation
> max_rt_quantum
||
115 info
->computation
< min_rt_quantum
) {
116 result
= KERN_INVALID_ARGUMENT
;
123 thread
->realtime
.period
= info
->period
;
124 thread
->realtime
.computation
= info
->computation
;
125 thread
->realtime
.constraint
= info
->constraint
;
126 thread
->realtime
.preemptible
= info
->preemptible
;
128 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
129 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
130 thread
->sched_mode
|= TH_MODE_REALTIME
;
131 thread_recompute_priority(thread
);
134 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
135 thread
->safe_mode
|= TH_MODE_REALTIME
;
138 thread_unlock(thread
);
144 case THREAD_PRECEDENCE_POLICY
:
146 thread_precedence_policy_t info
;
148 if (count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
149 result
= KERN_INVALID_ARGUMENT
;
153 info
= (thread_precedence_policy_t
)policy_info
;
158 thread
->importance
= info
->importance
;
160 thread_recompute_priority(thread
);
162 thread_unlock(thread
);
169 result
= KERN_INVALID_ARGUMENT
;
173 act_unlock_thread(act
);
179 thread_recompute_priority(
184 if (thread
->sched_mode
& TH_MODE_REALTIME
)
185 priority
= BASEPRI_REALTIME
;
187 if (thread
->importance
> MAXPRI
)
190 if (thread
->importance
< -MAXPRI
)
193 priority
= thread
->importance
;
195 priority
+= thread
->task_priority
;
197 if (priority
> thread
->max_priority
)
198 priority
= thread
->max_priority
;
200 if (priority
< MINPRI
)
204 set_priority(thread
, priority
);
208 thread_task_priority(
211 integer_t max_priority
)
215 assert(thread
!= THREAD_NULL
);
220 thread
->task_priority
= priority
;
221 thread
->max_priority
= max_priority
;
223 thread_recompute_priority(thread
);
225 thread_unlock(thread
);
232 thread_policy_flavor_t flavor
,
233 thread_policy_t policy_info
,
234 mach_msg_type_number_t
*count
,
235 boolean_t
*get_default
)
237 kern_return_t result
= KERN_SUCCESS
;
241 if (act
== THR_ACT_NULL
)
242 return (KERN_INVALID_ARGUMENT
);
244 thread
= act_lock_thread(act
);
246 act_unlock_thread(act
);
248 return (KERN_TERMINATED
);
251 assert(thread
!= THREAD_NULL
);
255 case THREAD_EXTENDED_POLICY
:
257 boolean_t timeshare
= TRUE
;
259 if (!(*get_default
)) {
263 if ( !(thread
->sched_mode
& TH_MODE_REALTIME
) &&
264 !(thread
->safe_mode
& TH_MODE_REALTIME
) ) {
265 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
))
266 timeshare
= (thread
->sched_mode
& TH_MODE_TIMESHARE
) != 0;
268 timeshare
= (thread
->safe_mode
& TH_MODE_TIMESHARE
) != 0;
273 thread_unlock(thread
);
277 if (*count
>= THREAD_EXTENDED_POLICY_COUNT
) {
278 thread_extended_policy_t info
;
280 info
= (thread_extended_policy_t
)policy_info
;
281 info
->timeshare
= timeshare
;
287 case THREAD_TIME_CONSTRAINT_POLICY
:
289 thread_time_constraint_policy_t info
;
291 if (*count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
292 result
= KERN_INVALID_ARGUMENT
;
296 info
= (thread_time_constraint_policy_t
)policy_info
;
298 if (!(*get_default
)) {
302 if ( (thread
->sched_mode
& TH_MODE_REALTIME
) ||
303 (thread
->safe_mode
& TH_MODE_REALTIME
) ) {
304 info
->period
= thread
->realtime
.period
;
305 info
->computation
= thread
->realtime
.computation
;
306 info
->constraint
= thread
->realtime
.constraint
;
307 info
->preemptible
= thread
->realtime
.preemptible
;
312 thread_unlock(thread
);
318 info
->computation
= std_quantum
/ 2;
319 info
->constraint
= std_quantum
;
320 info
->preemptible
= TRUE
;
326 case THREAD_PRECEDENCE_POLICY
:
328 thread_precedence_policy_t info
;
330 if (*count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
331 result
= KERN_INVALID_ARGUMENT
;
335 info
= (thread_precedence_policy_t
)policy_info
;
337 if (!(*get_default
)) {
341 info
->importance
= thread
->importance
;
343 thread_unlock(thread
);
347 info
->importance
= 0;
353 result
= KERN_INVALID_ARGUMENT
;
357 act_unlock_thread(act
);