]> git.saurik.com Git - apple/xnu.git/blob - osfmk/kern/task_policy.c
xnu-517.11.1.tar.gz
[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,
70 ((info->role == TASK_FOREGROUND_APPLICATION)?
71 BASEPRI_FOREGROUND: BASEPRI_BACKGROUND),
72 task->max_priority);
73 task->role = info->role;
74 break;
75
76 case TASK_CONTROL_APPLICATION:
77 case TASK_RENICED:
78 /* fail silently */
79 break;
80
81 default:
82 result = KERN_INVALID_ARGUMENT;
83 break;
84 }
85 }
86 else
87 if (info->role == TASK_CONTROL_APPLICATION) {
88 if ( task != current_task() ||
89 task->sec_token.val[0] != 0 )
90 result = KERN_INVALID_ARGUMENT;
91 else {
92 task_priority(task, BASEPRI_CONTROL, task->max_priority);
93 task->role = info->role;
94 }
95 }
96 else
97 if (info->role == TASK_GRAPHICS_SERVER) {
98 if ( task != current_task() ||
99 task->sec_token.val[0] != 0 )
100 result = KERN_INVALID_ARGUMENT;
101 else {
102 task_priority(task, MAXPRI_SYSTEM - 3, MAXPRI_SYSTEM);
103 task->role = info->role;
104 }
105 }
106 else
107 result = KERN_INVALID_ARGUMENT;
108
109 task_unlock(task);
110
111 break;
112 }
113
114 default:
115 result = KERN_INVALID_ARGUMENT;
116 break;
117 }
118
119 return (result);
120 }
121
122 static void
123 task_priority(
124 task_t task,
125 integer_t priority,
126 integer_t max_priority)
127 {
128 thread_act_t act;
129
130 task->max_priority = max_priority;
131
132 if (priority > task->max_priority)
133 priority = task->max_priority;
134 else
135 if (priority < MINPRI)
136 priority = MINPRI;
137
138 task->priority = priority;
139
140 queue_iterate(&task->threads, act, thread_act_t, task_threads) {
141 thread_t thread = act_lock_thread(act);
142
143 if (act->active)
144 thread_task_priority(thread, priority, max_priority);
145
146 act_unlock_thread(act);
147 }
148 }
149
150 kern_return_t
151 task_importance(
152 task_t task,
153 integer_t importance)
154 {
155 if (task == TASK_NULL || task == kernel_task)
156 return (KERN_INVALID_ARGUMENT);
157
158 task_lock(task);
159
160 if (!task->active) {
161 task_unlock(task);
162
163 return (KERN_TERMINATED);
164 }
165
166 if (task->role >= TASK_CONTROL_APPLICATION) {
167 task_unlock(task);
168
169 return (KERN_INVALID_ARGUMENT);
170 }
171
172 task_priority(task, importance + BASEPRI_DEFAULT, task->max_priority);
173 task->role = TASK_RENICED;
174
175 task_unlock(task);
176
177 return (KERN_SUCCESS);
178 }
179
180 kern_return_t
181 task_policy_get(
182 task_t task,
183 task_policy_flavor_t flavor,
184 task_policy_t policy_info,
185 mach_msg_type_number_t *count,
186 boolean_t *get_default)
187 {
188 if (task == TASK_NULL || task == kernel_task)
189 return (KERN_INVALID_ARGUMENT);
190
191 switch (flavor) {
192
193 case TASK_CATEGORY_POLICY:
194 {
195 task_category_policy_t info = (task_category_policy_t)policy_info;
196
197 if (*count < TASK_CATEGORY_POLICY_COUNT)
198 return (KERN_INVALID_ARGUMENT);
199
200 if (*get_default)
201 info->role = TASK_UNSPECIFIED;
202 else {
203 task_lock(task);
204 info->role = task->role;
205 task_unlock(task);
206 }
207 break;
208 }
209
210 default:
211 return (KERN_INVALID_ARGUMENT);
212 }
213
214 return (KERN_SUCCESS);
215 }