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