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/processor.h>
32 #include <kern/thread.h>
35 thread_recompute_priority(
41 thread_policy_flavor_t flavor
,
42 thread_policy_t policy_info
,
43 mach_msg_type_number_t count
)
45 kern_return_t result
= KERN_SUCCESS
;
49 if (act
== THR_ACT_NULL
)
50 return (KERN_INVALID_ARGUMENT
);
52 thread
= act_lock_thread(act
);
54 act_unlock_thread(act
);
56 return (KERN_TERMINATED
);
59 assert(thread
!= THREAD_NULL
);
63 case THREAD_EXTENDED_POLICY
:
65 boolean_t timeshare
= TRUE
;
67 if (count
>= THREAD_EXTENDED_POLICY_COUNT
) {
68 thread_extended_policy_t info
;
70 info
= (thread_extended_policy_t
)policy_info
;
71 timeshare
= info
->timeshare
;
77 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
78 integer_t oldmode
= (thread
->sched_mode
& TH_MODE_TIMESHARE
);
80 thread
->sched_mode
&= ~TH_MODE_REALTIME
;
82 if (timeshare
&& !oldmode
) {
83 thread
->sched_mode
|= TH_MODE_TIMESHARE
;
85 if (thread
->state
& TH_RUN
)
86 pset_share_incr(thread
->processor_set
);
89 if (!timeshare
&& oldmode
) {
90 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
92 if (thread
->state
& TH_RUN
)
93 pset_share_decr(thread
->processor_set
);
96 thread_recompute_priority(thread
);
99 thread
->safe_mode
&= ~TH_MODE_REALTIME
;
102 thread
->safe_mode
|= TH_MODE_TIMESHARE
;
104 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
107 thread_unlock(thread
);
113 case THREAD_TIME_CONSTRAINT_POLICY
:
115 thread_time_constraint_policy_t info
;
117 if (count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
118 result
= KERN_INVALID_ARGUMENT
;
122 info
= (thread_time_constraint_policy_t
)policy_info
;
123 if ( info
->constraint
< info
->computation
||
124 info
->computation
> max_rt_quantum
||
125 info
->computation
< min_rt_quantum
) {
126 result
= KERN_INVALID_ARGUMENT
;
133 thread
->realtime
.period
= info
->period
;
134 thread
->realtime
.computation
= info
->computation
;
135 thread
->realtime
.constraint
= info
->constraint
;
136 thread
->realtime
.preemptible
= info
->preemptible
;
138 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
)) {
139 if (thread
->sched_mode
& TH_MODE_TIMESHARE
) {
140 thread
->sched_mode
&= ~TH_MODE_TIMESHARE
;
142 if (thread
->state
& TH_RUN
)
143 pset_share_decr(thread
->processor_set
);
145 thread
->sched_mode
|= TH_MODE_REALTIME
;
146 thread_recompute_priority(thread
);
149 thread
->safe_mode
&= ~TH_MODE_TIMESHARE
;
150 thread
->safe_mode
|= TH_MODE_REALTIME
;
153 thread_unlock(thread
);
159 case THREAD_PRECEDENCE_POLICY
:
161 thread_precedence_policy_t info
;
163 if (count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
164 result
= KERN_INVALID_ARGUMENT
;
168 info
= (thread_precedence_policy_t
)policy_info
;
173 thread
->importance
= info
->importance
;
175 thread_recompute_priority(thread
);
177 thread_unlock(thread
);
184 result
= KERN_INVALID_ARGUMENT
;
188 act_unlock_thread(act
);
194 thread_recompute_priority(
199 if (thread
->sched_mode
& TH_MODE_REALTIME
)
200 priority
= BASEPRI_RTQUEUES
;
202 if (thread
->importance
> MAXPRI
)
205 if (thread
->importance
< -MAXPRI
)
208 priority
= thread
->importance
;
210 priority
+= thread
->task_priority
;
212 if (priority
> thread
->max_priority
)
213 priority
= thread
->max_priority
;
215 if (priority
< MINPRI
)
219 set_priority(thread
, priority
);
223 thread_task_priority(
226 integer_t max_priority
)
230 assert(thread
!= THREAD_NULL
);
235 thread
->task_priority
= priority
;
236 thread
->max_priority
= max_priority
;
238 thread_recompute_priority(thread
);
240 thread_unlock(thread
);
247 thread_policy_flavor_t flavor
,
248 thread_policy_t policy_info
,
249 mach_msg_type_number_t
*count
,
250 boolean_t
*get_default
)
252 kern_return_t result
= KERN_SUCCESS
;
256 if (act
== THR_ACT_NULL
)
257 return (KERN_INVALID_ARGUMENT
);
259 thread
= act_lock_thread(act
);
261 act_unlock_thread(act
);
263 return (KERN_TERMINATED
);
266 assert(thread
!= THREAD_NULL
);
270 case THREAD_EXTENDED_POLICY
:
272 boolean_t timeshare
= TRUE
;
274 if (!(*get_default
)) {
278 if ( !(thread
->sched_mode
& TH_MODE_REALTIME
) &&
279 !(thread
->safe_mode
& TH_MODE_REALTIME
) ) {
280 if (!(thread
->sched_mode
& TH_MODE_FAILSAFE
))
281 timeshare
= (thread
->sched_mode
& TH_MODE_TIMESHARE
) != 0;
283 timeshare
= (thread
->safe_mode
& TH_MODE_TIMESHARE
) != 0;
288 thread_unlock(thread
);
292 if (*count
>= THREAD_EXTENDED_POLICY_COUNT
) {
293 thread_extended_policy_t info
;
295 info
= (thread_extended_policy_t
)policy_info
;
296 info
->timeshare
= timeshare
;
302 case THREAD_TIME_CONSTRAINT_POLICY
:
304 thread_time_constraint_policy_t info
;
306 if (*count
< THREAD_TIME_CONSTRAINT_POLICY_COUNT
) {
307 result
= KERN_INVALID_ARGUMENT
;
311 info
= (thread_time_constraint_policy_t
)policy_info
;
313 if (!(*get_default
)) {
317 if ( (thread
->sched_mode
& TH_MODE_REALTIME
) ||
318 (thread
->safe_mode
& TH_MODE_REALTIME
) ) {
319 info
->period
= thread
->realtime
.period
;
320 info
->computation
= thread
->realtime
.computation
;
321 info
->constraint
= thread
->realtime
.constraint
;
322 info
->preemptible
= thread
->realtime
.preemptible
;
327 thread_unlock(thread
);
333 info
->computation
= std_quantum
/ 2;
334 info
->constraint
= std_quantum
;
335 info
->preemptible
= TRUE
;
341 case THREAD_PRECEDENCE_POLICY
:
343 thread_precedence_policy_t info
;
345 if (*count
< THREAD_PRECEDENCE_POLICY_COUNT
) {
346 result
= KERN_INVALID_ARGUMENT
;
350 info
= (thread_precedence_policy_t
)policy_info
;
352 if (!(*get_default
)) {
356 info
->importance
= thread
->importance
;
358 thread_unlock(thread
);
362 info
->importance
= 0;
368 result
= KERN_INVALID_ARGUMENT
;
372 act_unlock_thread(act
);