]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/task_policy.c
xnu-344.49.tar.gz
[apple/xnu.git] / osfmk / kern / task_policy.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
43866e37 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
43866e37
A
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
13 * file.
14 *
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
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
43866e37
A
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.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
27 *
28 * HISTORY
29 *
30 * 15 October 2000 (debo)
31 * Created.
32 */
33
0b4e3aa0
A
34#include <kern/task.h>
35
36static void
37task_priority(
38 task_t task,
39 integer_t priority,
40 integer_t max_priority);
1c79356b
A
41
42kern_return_t
43task_policy_set(
44 task_t task,
45 task_policy_flavor_t flavor,
46 task_policy_t policy_info,
47 mach_msg_type_number_t count)
48{
0b4e3aa0
A
49 kern_return_t result = KERN_SUCCESS;
50
51 if (task == TASK_NULL || task == kernel_task)
1c79356b
A
52 return (KERN_INVALID_ARGUMENT);
53
54 switch (flavor) {
55
56 case TASK_CATEGORY_POLICY:
57 {
58 task_category_policy_t info = (task_category_policy_t)policy_info;
59
60 if (count < TASK_CATEGORY_POLICY_COUNT)
61 return (KERN_INVALID_ARGUMENT);
62
0b4e3aa0
A
63 task_lock(task);
64
65 if ( info->role == TASK_FOREGROUND_APPLICATION ||
66 info->role == TASK_BACKGROUND_APPLICATION ) {
67 switch (task->role) {
68
69 case TASK_FOREGROUND_APPLICATION:
70 case TASK_BACKGROUND_APPLICATION:
71 case TASK_UNSPECIFIED:
9bccf70c
A
72 task_priority(task,
73 ((info->role == TASK_FOREGROUND_APPLICATION)?
74 BASEPRI_FOREGROUND: BASEPRI_BACKGROUND),
0b4e3aa0
A
75 task->max_priority);
76 task->role = info->role;
77 break;
78
79 case TASK_CONTROL_APPLICATION:
80 case TASK_RENICED:
81 /* fail silently */
82 break;
83
84 default:
85 result = KERN_INVALID_ARGUMENT;
86 break;
87 }
1c79356b 88 }
0b4e3aa0
A
89 else
90 if (info->role == TASK_CONTROL_APPLICATION) {
91 if ( task != current_task() ||
92 task->sec_token.val[0] != 0 )
93 result = KERN_INVALID_ARGUMENT;
94 else {
9bccf70c 95 task_priority(task, BASEPRI_CONTROL, task->max_priority);
0b4e3aa0
A
96 task->role = info->role;
97 }
98 }
99 else
100 if (info->role == TASK_GRAPHICS_SERVER) {
101 if ( task != current_task() ||
102 task->sec_token.val[0] != 0 )
103 result = KERN_INVALID_ARGUMENT;
104 else {
105 task_priority(task, MAXPRI_SYSTEM - 3, MAXPRI_SYSTEM);
106 task->role = info->role;
107 }
108 }
109 else
110 result = KERN_INVALID_ARGUMENT;
111
112 task_unlock(task);
1c79356b
A
113
114 break;
115 }
116
117 default:
0b4e3aa0
A
118 result = KERN_INVALID_ARGUMENT;
119 break;
120 }
121
122 return (result);
123}
124
125static void
126task_priority(
127 task_t task,
128 integer_t priority,
129 integer_t max_priority)
130{
131 thread_act_t act;
132
133 task->max_priority = max_priority;
134
135 if (priority > task->max_priority)
136 priority = task->max_priority;
137 else
138 if (priority < MINPRI)
139 priority = MINPRI;
140
141 task->priority = priority;
142
143 queue_iterate(&task->thr_acts, act, thread_act_t, thr_acts) {
144 thread_t thread = act_lock_thread(act);
145
146 if (act->active)
147 thread_task_priority(thread, priority, max_priority);
148
149 act_unlock_thread(act);
150 }
151}
152
153kern_return_t
154task_importance(
155 task_t task,
156 integer_t importance)
157{
158 if (task == TASK_NULL || task == kernel_task)
159 return (KERN_INVALID_ARGUMENT);
160
161 task_lock(task);
162
163 if (!task->active) {
164 task_unlock(task);
165
166 return (KERN_TERMINATED);
167 }
168
169 if (task->role >= TASK_CONTROL_APPLICATION) {
170 task_unlock(task);
171
1c79356b
A
172 return (KERN_INVALID_ARGUMENT);
173 }
174
0b4e3aa0
A
175 task_priority(task, importance + BASEPRI_DEFAULT, task->max_priority);
176 task->role = TASK_RENICED;
177
178 task_unlock(task);
179
1c79356b
A
180 return (KERN_SUCCESS);
181}
0b4e3aa0 182
1c79356b
A
183kern_return_t
184task_policy_get(
185 task_t task,
186 task_policy_flavor_t flavor,
187 task_policy_t policy_info,
188 mach_msg_type_number_t *count,
189 boolean_t *get_default)
190{
0b4e3aa0 191 if (task == TASK_NULL || task == kernel_task)
1c79356b
A
192 return (KERN_INVALID_ARGUMENT);
193
194 switch (flavor) {
195
196 case TASK_CATEGORY_POLICY:
197 {
198 task_category_policy_t info = (task_category_policy_t)policy_info;
199
200 if (*count < TASK_CATEGORY_POLICY_COUNT)
201 return (KERN_INVALID_ARGUMENT);
202
0b4e3aa0
A
203 if (*get_default)
204 info->role = TASK_UNSPECIFIED;
205 else {
206 task_lock(task);
207 info->role = task->role;
208 task_unlock(task);
209 }
1c79356b
A
210 break;
211 }
212
213 default:
214 return (KERN_INVALID_ARGUMENT);
215 }
216
217 return (KERN_SUCCESS);
218}