]> git.saurik.com Git - apple/xnu.git/blame - osfmk/kern/task_policy.c
xnu-1504.7.4.tar.gz
[apple/xnu.git] / osfmk / kern / task_policy.c
CommitLineData
1c79356b 1/*
91447636 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
1c79356b 3 *
2d21ac55 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
2d21ac55
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
8f6c56a5 14 *
2d21ac55
A
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
2d21ac55
A
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
8f6c56a5 25 *
2d21ac55 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b 27 */
1c79356b 28
91447636
A
29#include <mach/mach_types.h>
30#include <mach/task_server.h>
31
32#include <kern/sched.h>
0b4e3aa0
A
33#include <kern/task.h>
34
35static void
36task_priority(
37 task_t task,
38 integer_t priority,
39 integer_t max_priority);
1c79356b
A
40
41kern_return_t
42task_policy_set(
43 task_t task,
44 task_policy_flavor_t flavor,
45 task_policy_t policy_info,
46 mach_msg_type_number_t count)
47{
0b4e3aa0
A
48 kern_return_t result = KERN_SUCCESS;
49
50 if (task == TASK_NULL || task == kernel_task)
1c79356b
A
51 return (KERN_INVALID_ARGUMENT);
52
53 switch (flavor) {
54
55 case TASK_CATEGORY_POLICY:
56 {
57 task_category_policy_t info = (task_category_policy_t)policy_info;
58
59 if (count < TASK_CATEGORY_POLICY_COUNT)
60 return (KERN_INVALID_ARGUMENT);
61
0b4e3aa0
A
62 task_lock(task);
63
64 if ( info->role == TASK_FOREGROUND_APPLICATION ||
65 info->role == TASK_BACKGROUND_APPLICATION ) {
66 switch (task->role) {
67
68 case TASK_FOREGROUND_APPLICATION:
69 case TASK_BACKGROUND_APPLICATION:
70 case TASK_UNSPECIFIED:
9bccf70c
A
71 task_priority(task,
72 ((info->role == TASK_FOREGROUND_APPLICATION)?
73 BASEPRI_FOREGROUND: BASEPRI_BACKGROUND),
0b4e3aa0
A
74 task->max_priority);
75 task->role = info->role;
76 break;
77
78 case TASK_CONTROL_APPLICATION:
79 case TASK_RENICED:
80 /* fail silently */
81 break;
82
83 default:
84 result = KERN_INVALID_ARGUMENT;
85 break;
86 }
1c79356b 87 }
0b4e3aa0
A
88 else
89 if (info->role == TASK_CONTROL_APPLICATION) {
90 if ( task != current_task() ||
91 task->sec_token.val[0] != 0 )
92 result = KERN_INVALID_ARGUMENT;
93 else {
9bccf70c 94 task_priority(task, BASEPRI_CONTROL, task->max_priority);
0b4e3aa0
A
95 task->role = info->role;
96 }
97 }
98 else
99 if (info->role == TASK_GRAPHICS_SERVER) {
100 if ( task != current_task() ||
101 task->sec_token.val[0] != 0 )
102 result = KERN_INVALID_ARGUMENT;
103 else {
91447636 104 task_priority(task, MAXPRI_RESERVED - 3, MAXPRI_RESERVED);
0b4e3aa0
A
105 task->role = info->role;
106 }
107 }
b7266188
A
108 else
109 if (info->role == TASK_THROTTLE_APPLICATION) {
110 task_priority(task, MAXPRI_THROTTLE, MAXPRI_THROTTLE);
111 task->role = info->role;
112 }
113 else
114 if (info->role == TASK_DEFAULT_APPLICATION) {
115 task_priority(task, BASEPRI_DEFAULT, MAXPRI_USER);
116 task->role = info->role;
117 }
0b4e3aa0
A
118 else
119 result = KERN_INVALID_ARGUMENT;
120
121 task_unlock(task);
1c79356b
A
122
123 break;
124 }
125
126 default:
0b4e3aa0
A
127 result = KERN_INVALID_ARGUMENT;
128 break;
129 }
130
131 return (result);
132}
133
134static void
135task_priority(
136 task_t task,
137 integer_t priority,
138 integer_t max_priority)
139{
91447636 140 thread_t thread;
0b4e3aa0
A
141
142 task->max_priority = max_priority;
143
144 if (priority > task->max_priority)
145 priority = task->max_priority;
146 else
147 if (priority < MINPRI)
148 priority = MINPRI;
149
150 task->priority = priority;
151
91447636
A
152 queue_iterate(&task->threads, thread, thread_t, task_threads) {
153 thread_mtx_lock(thread);
0b4e3aa0 154
91447636 155 if (thread->active)
0b4e3aa0
A
156 thread_task_priority(thread, priority, max_priority);
157
91447636 158 thread_mtx_unlock(thread);
0b4e3aa0
A
159 }
160}
161
162kern_return_t
163task_importance(
164 task_t task,
165 integer_t importance)
166{
167 if (task == TASK_NULL || task == kernel_task)
168 return (KERN_INVALID_ARGUMENT);
169
170 task_lock(task);
171
172 if (!task->active) {
173 task_unlock(task);
174
175 return (KERN_TERMINATED);
176 }
177
178 if (task->role >= TASK_CONTROL_APPLICATION) {
179 task_unlock(task);
180
1c79356b
A
181 return (KERN_INVALID_ARGUMENT);
182 }
183
0b4e3aa0
A
184 task_priority(task, importance + BASEPRI_DEFAULT, task->max_priority);
185 task->role = TASK_RENICED;
186
187 task_unlock(task);
188
1c79356b
A
189 return (KERN_SUCCESS);
190}
0b4e3aa0 191
1c79356b
A
192kern_return_t
193task_policy_get(
194 task_t task,
195 task_policy_flavor_t flavor,
196 task_policy_t policy_info,
197 mach_msg_type_number_t *count,
198 boolean_t *get_default)
199{
0b4e3aa0 200 if (task == TASK_NULL || task == kernel_task)
1c79356b
A
201 return (KERN_INVALID_ARGUMENT);
202
203 switch (flavor) {
204
205 case TASK_CATEGORY_POLICY:
206 {
207 task_category_policy_t info = (task_category_policy_t)policy_info;
208
209 if (*count < TASK_CATEGORY_POLICY_COUNT)
210 return (KERN_INVALID_ARGUMENT);
211
0b4e3aa0
A
212 if (*get_default)
213 info->role = TASK_UNSPECIFIED;
214 else {
215 task_lock(task);
216 info->role = task->role;
217 task_unlock(task);
218 }
1c79356b
A
219 break;
220 }
221
222 default:
223 return (KERN_INVALID_ARGUMENT);
224 }
225
226 return (KERN_SUCCESS);
227}