2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
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.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
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
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
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.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
29 #include <mach/mach_types.h>
30 #include <mach/task_server.h>
32 #include <kern/sched.h>
33 #include <kern/task.h>
34 #include <mach/thread_policy.h>
35 #include <sys/errno.h>
36 #include <sys/resource.h>
37 #include <machine/limits.h>
39 static int proc_apply_bgtaskpolicy_locked(task_t task
, int, int);
40 static int proc_restore_bgtaskpolicy_locked(task_t
, int, int, int);
41 static int task_get_cpuusage(task_t task
, uint32_t * percentagep
, uint64_t * intervalp
, uint64_t * deadlinep
);
42 static int task_set_cpuusage(task_t task
, uint32_t percentage
, uint64_t interval
, uint64_t deadline
);
43 static int task_apply_resource_actions(task_t task
, int type
);
44 static int proc_apply_bgthreadpolicy_locked(thread_t thread
, int selfset
);
45 static void restore_bgthreadpolicy_locked(thread_t thread
, int selfset
);
47 process_policy_t default_task_proc_policy
= {0,
49 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
50 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
51 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
52 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
53 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
54 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
55 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
57 TASK_POLICY_HWACCESS_CPU_ATTRIBUTE_ALL
,
58 TASK_POLICY_HWACCESS_NET_ATTRIBUTE_NORMAL
,
59 TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_FULLACCESS
,
60 TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
,
61 TASK_POLICY_BACKGROUND_ATTRIBUTE_ALL
64 process_policy_t default_task_null_policy
= {0,
66 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
67 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
68 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
69 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
70 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
71 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
72 TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
,
74 TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NONE
,
75 TASK_POLICY_HWACCESS_NET_ATTRIBUTE_NONE
,
76 TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NONE
,
77 TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
,
78 TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
86 integer_t max_priority
);
91 task_policy_flavor_t flavor
,
92 task_policy_t policy_info
,
93 mach_msg_type_number_t count
)
95 kern_return_t result
= KERN_SUCCESS
;
96 void * bsdinfo
= NULL
;
99 if (task
== TASK_NULL
|| task
== kernel_task
)
100 return (KERN_INVALID_ARGUMENT
);
104 case TASK_CATEGORY_POLICY
:
106 task_category_policy_t info
= (task_category_policy_t
)policy_info
;
108 if (count
< TASK_CATEGORY_POLICY_COUNT
)
109 return (KERN_INVALID_ARGUMENT
);
112 if ((current_task() == task
) && (info
!= NULL
) &&
113 (info
->role
!= TASK_THROTTLE_APPLICATION
))
114 return (KERN_INVALID_ARGUMENT
);
118 if ( info
->role
== TASK_FOREGROUND_APPLICATION
||
119 info
->role
== TASK_BACKGROUND_APPLICATION
) {
121 if (task
->ext_actionstate
.apptype
!= PROC_POLICY_OSX_APPTYPE_NONE
) {
122 switch (info
->role
) {
123 case TASK_FOREGROUND_APPLICATION
:
124 switch (task
->ext_actionstate
.apptype
) {
125 case PROC_POLICY_OSX_APPTYPE_TAL
:
126 /* Move the app to foreground with no DarwinBG */
127 proc_restore_bgtaskpolicy_locked(task
, 1, 1, BASEPRI_FOREGROUND
);
128 bsdinfo
= task
->bsd_info
;
132 case PROC_POLICY_OSX_APPTYPE_DBCLIENT
:
133 /* reset the apptype so enforcement on background/foregound */
134 task
->ext_actionstate
.apptype
= PROC_POLICY_OSX_APPTYPE_NONE
;
135 /* Internal application and make it foreground pri */
136 proc_restore_bgtaskpolicy_locked(task
, 1, 0, BASEPRI_FOREGROUND
);
137 bsdinfo
= task
->bsd_info
;
142 /* the app types cannot be in CONTROL, GRAPHICS STATE, so it will de default state here */
144 ((info
->role
== TASK_FOREGROUND_APPLICATION
)?
145 BASEPRI_FOREGROUND
: BASEPRI_BACKGROUND
),
149 task
->role
= TASK_FOREGROUND_APPLICATION
;
152 case TASK_BACKGROUND_APPLICATION
:
153 switch (task
->ext_actionstate
.apptype
) {
154 case PROC_POLICY_OSX_APPTYPE_TAL
:
155 /* TAL apps will get Darwin backgrounded if not already set */
156 if (task
->ext_actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) {
157 /* external application of Darwin BG */
158 proc_apply_bgtaskpolicy_locked(task
, 1, 1);
159 bsdinfo
= task
->bsd_info
;
166 ((info
->role
== TASK_FOREGROUND_APPLICATION
)?
167 BASEPRI_FOREGROUND
: BASEPRI_BACKGROUND
),
171 task
->role
= TASK_BACKGROUND_APPLICATION
;
178 } /* switch info->role */
179 } else { /* apptype != PROC_POLICY_OSX_APPTYPE_NONE */
180 #endif /* !CONFIG_EMBEDDED */
181 switch (task
->role
) {
183 case TASK_FOREGROUND_APPLICATION
:
184 case TASK_BACKGROUND_APPLICATION
:
185 case TASK_UNSPECIFIED
:
186 /* if there are no process wide backgrounding ... */
187 if ((task
->ext_actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) &&
188 (task
->actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
)) {
190 ((info
->role
== TASK_FOREGROUND_APPLICATION
)?
191 BASEPRI_FOREGROUND
: BASEPRI_BACKGROUND
),
194 task
->role
= info
->role
;
197 case TASK_CONTROL_APPLICATION
:
199 /* else fail silently */
203 result
= KERN_INVALID_ARGUMENT
;
207 } /* apptype != PROC_POLICY_OSX_APPTYPE_NONE */
208 #endif /* !CONFIG_EMBEDDED */
210 } else if (info
->role
== TASK_CONTROL_APPLICATION
) {
211 if (task
!= current_task()||
212 task
->sec_token
.val
[0] != 0)
213 result
= KERN_INVALID_ARGUMENT
;
215 task_priority(task
, BASEPRI_CONTROL
, task
->max_priority
);
216 task
->role
= info
->role
;
218 } else if (info
->role
== TASK_GRAPHICS_SERVER
) {
219 if (task
!= current_task() ||
220 task
->sec_token
.val
[0] != 0)
221 result
= KERN_INVALID_ARGUMENT
;
223 task_priority(task
, MAXPRI_RESERVED
- 3, MAXPRI_RESERVED
);
224 task
->role
= info
->role
;
228 if (info
->role
== TASK_THROTTLE_APPLICATION
) {
229 task_priority(task
, MAXPRI_THROTTLE
, MAXPRI_THROTTLE
);
230 task
->role
= info
->role
;
231 } else if (info
->role
== TASK_DEFAULT_APPLICATION
|| info
->role
== TASK_NONUI_APPLICATION
)
233 task_priority(task
, BASEPRI_DEFAULT
, MAXPRI_USER
);
234 task
->role
= info
->role
;
236 #else /* CONFIG_EMBEDDED */
237 if (info
->role
== TASK_DEFAULT_APPLICATION
)
239 task_priority(task
, BASEPRI_DEFAULT
, MAXPRI_USER
);
240 task
->role
= info
->role
;
242 #endif /* CONFIG_EMBEDDED */
243 result
= KERN_INVALID_ARGUMENT
;
247 /* if backgrounding action ... */
249 proc_set_task_networkbg(bsdinfo
, setbg
);
255 result
= KERN_INVALID_ARGUMENT
;
266 integer_t max_priority
)
270 task
->max_priority
= max_priority
;
272 if (priority
> task
->max_priority
)
273 priority
= task
->max_priority
;
275 if (priority
< MINPRI
)
278 task
->priority
= priority
;
280 queue_iterate(&task
->threads
, thread
, thread_t
, task_threads
) {
281 thread_mtx_lock(thread
);
284 thread_task_priority(thread
, priority
, max_priority
);
286 thread_mtx_unlock(thread
);
293 integer_t importance
)
295 if (task
== TASK_NULL
|| task
== kernel_task
)
296 return (KERN_INVALID_ARGUMENT
);
303 return (KERN_TERMINATED
);
306 if (task
->role
>= TASK_CONTROL_APPLICATION
) {
309 return (KERN_INVALID_ARGUMENT
);
312 task_priority(task
, importance
+ BASEPRI_DEFAULT
, task
->max_priority
);
313 task
->role
= TASK_RENICED
;
317 return (KERN_SUCCESS
);
323 task_policy_flavor_t flavor
,
324 task_policy_t policy_info
,
325 mach_msg_type_number_t
*count
,
326 boolean_t
*get_default
)
328 if (task
== TASK_NULL
|| task
== kernel_task
)
329 return (KERN_INVALID_ARGUMENT
);
333 case TASK_CATEGORY_POLICY
:
335 task_category_policy_t info
= (task_category_policy_t
)policy_info
;
337 if (*count
< TASK_CATEGORY_POLICY_COUNT
)
338 return (KERN_INVALID_ARGUMENT
);
341 info
->role
= TASK_UNSPECIFIED
;
344 info
->role
= task
->role
;
351 return (KERN_INVALID_ARGUMENT
);
354 return (KERN_SUCCESS
);
357 /* task Darwin BG enforcement/settings related routines */
359 proc_get_task_bg_policy(task_t task
)
365 if (current_task() == task
)
369 val
= task
->ext_policystate
.hw_bg
;
371 val
= task
->policystate
.hw_bg
;
379 proc_get_thread_bg_policy(task_t task
, uint64_t tid
)
381 thread_t self
= current_thread();
382 thread_t thread
= THREAD_NULL
;
385 if (tid
== self
->thread_id
) {
386 val
= self
->policystate
.hw_bg
;
389 thread
= task_findtid(task
, tid
);
391 val
= thread
->ext_policystate
.hw_bg
;
399 proc_get_self_isbackground(void)
401 task_t task
= current_task();;
402 thread_t thread
= current_thread();
404 if ((task
->ext_actionstate
.hw_bg
!= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) ||
405 (task
->actionstate
.hw_bg
!= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) ||
406 (thread
->ext_actionstate
.hw_bg
!= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) ||
407 (thread
->actionstate
.hw_bg
!= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
))
414 int proc_get_selfthread_isbackground(void)
416 thread_t thread
= current_thread();
418 if ((thread
->ext_actionstate
.hw_bg
!= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) ||
419 (thread
->actionstate
.hw_bg
!= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
))
427 proc_set_bgtaskpolicy(task_t task
, int intval
)
432 if (current_task() == task
)
439 if (task
->ext_policystate
.hw_bg
!= intval
)
440 task
->ext_policystate
.hw_bg
= intval
;
442 if (task
->policystate
.hw_bg
!= intval
)
443 task
->policystate
.hw_bg
= intval
;
450 /* set and apply as well */
451 int proc_set1_bgtaskpolicy(task_t task
, int prio
)
455 if (prio
== PRIO_DARWIN_BG
) {
456 error
= proc_set_bgtaskpolicy(task
, TASK_POLICY_BACKGROUND_ATTRIBUTE_ALL
);
458 error
= proc_apply_bgtaskpolicy(task
);
460 error
= proc_restore_bgtaskpolicy(task
);
468 proc_set_bgthreadpolicy(task_t task
, uint64_t tid
, int prio
)
470 thread_t self
= current_thread();
471 thread_t thread
= THREAD_NULL
;
477 if (tid
== self
->thread_id
) {
478 self
->policystate
.hw_bg
= prio
;
480 thread
= task_findtid(task
, tid
);
482 thread
->ext_policystate
.hw_bg
= prio
;
491 proc_set1_bgthreadpolicy(task_t task
, uint64_t tid
, int prio
)
495 if (prio
== PRIO_DARWIN_BG
) {
496 error
= proc_set_bgthreadpolicy(task
, tid
, TASK_POLICY_BACKGROUND_ATTRIBUTE_ALL
);
498 error
= proc_apply_bgthreadpolicy(task
, tid
);
500 error
= proc_restore_bgthreadpolicy(task
, tid
);
507 proc_add_bgtaskpolicy(task_t task
, int val
)
511 if (current_task() == task
)
517 task
->policystate
.hw_bg
|= val
;
519 task
->ext_policystate
.hw_bg
|= val
;
527 proc_add_bgthreadpolicy(task_t task
, uint64_t tid
, int val
)
529 thread_t self
= current_thread();
530 thread_t thread
= THREAD_NULL
;
536 if (tid
== self
->thread_id
) {
537 self
->policystate
.hw_bg
|= val
;
539 thread
= task_findtid(task
, tid
);
541 thread
->ext_policystate
.hw_bg
|= val
;
550 proc_remove_bgtaskpolicy(task_t task
, int intval
)
554 if (current_task() == task
)
560 task
->policystate
.hw_bg
&= ~intval
;
562 task
->ext_policystate
.hw_bg
&= ~intval
;
570 proc_remove_bgthreadpolicy(task_t task
, uint64_t tid
, int val
)
572 thread_t self
= current_thread();
573 thread_t thread
= THREAD_NULL
;
579 if (tid
== self
->thread_id
) {
580 self
->policystate
.hw_bg
&= ~val
;
582 thread
= task_findtid(task
, tid
);
584 thread
->ext_policystate
.hw_bg
&= ~val
;
593 proc_apply_bgtask_selfpolicy(void)
595 return(proc_apply_bgtaskpolicy(current_task()));
599 proc_apply_bgtaskpolicy(task_t task
)
603 if (task
== current_task())
606 return(proc_apply_bgtaskpolicy_locked(task
, 0, external
));
610 proc_apply_bgtaskpolicy_external(task_t task
)
612 return(proc_apply_bgtaskpolicy_locked(task
, 0, 1));
617 proc_apply_bgtaskpolicy_internal(task_t task
)
619 return(proc_apply_bgtaskpolicy_locked(task
, 0, 0));
624 proc_apply_bgtaskpolicy_locked(task_t task
, int locked
, int external
)
631 if (task
->ext_actionstate
.hw_bg
!= task
->ext_policystate
.hw_bg
) {
632 task
->ext_actionstate
.hw_bg
= task
->ext_policystate
.hw_bg
;
633 task_priority(task
, MAXPRI_THROTTLE
, MAXPRI_THROTTLE
);
634 /* background state applied */
637 if (task
->actionstate
.hw_bg
!= task
->policystate
.hw_bg
) {
638 task
->actionstate
.hw_bg
= task
->policystate
.hw_bg
;
639 task_priority(task
, MAXPRI_THROTTLE
, MAXPRI_THROTTLE
);
647 /* apply the self backgrounding even if the thread is not current thread/task(timer threads) */
649 proc_apply_workq_bgthreadpolicy(thread_t thread
)
652 task_t wqtask
= TASK_NULL
;
654 if (thread
!= THREAD_NULL
) {
655 wqtask
= thread
->task
;
657 /* apply the background as selfset internal one */
658 error
= proc_apply_bgthreadpolicy_locked(thread
, 1);
667 proc_apply_bgthreadpolicy(task_t task
, uint64_t tid
)
669 thread_t self
= current_thread();
670 thread_t thread
= THREAD_NULL
;
671 int selfset
= 0, error
= 0;
672 task_t localtask
= TASK_NULL
;
674 if (tid
== self
->thread_id
) {
676 localtask
= current_task();
681 task_lock(localtask
);
685 thread
= task_findtid(task
, tid
);
688 error
= proc_apply_bgthreadpolicy_locked(thread
, selfset
);
689 task_unlock(localtask
);
695 proc_apply_bgthreadpolicy_locked(thread_t thread
, int selfset
)
698 thread_precedence_policy_data_t policy
;
700 if (thread
!= NULL
) {
702 /* internal application */
703 if (thread
->actionstate
.hw_bg
!= thread
->policystate
.hw_bg
) {
704 thread
->actionstate
.hw_bg
= thread
->policystate
.hw_bg
;
705 if (thread
->ext_actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
)
710 /* external application */
711 if (thread
->ext_actionstate
.hw_bg
!= thread
->ext_policystate
.hw_bg
) {
712 thread
->ext_actionstate
.hw_bg
= thread
->ext_policystate
.hw_bg
;
713 if (thread
->actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
)
719 /* set thread priority (we did not save previous value) */
720 policy
.importance
= INT_MIN
;
722 thread_policy_set_internal(thread
, THREAD_PRECEDENCE_POLICY
,
723 (thread_policy_t
)&policy
,
724 THREAD_PRECEDENCE_POLICY_COUNT
);
734 proc_apply_bgthread_selfpolicy(void)
736 return(proc_apply_bgthreadpolicy(current_task(), current_thread()->thread_id
));
741 proc_restore_bgtaskpolicy(task_t task
)
745 if (current_task() == task
)
747 return(proc_restore_bgtaskpolicy_locked(task
, 0, external
, BASEPRI_DEFAULT
));
751 proc_restore_bgtaskpolicy_locked(task_t task
, int locked
, int external
, int pri
)
757 task
->ext_actionstate
.hw_bg
= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
;
758 /* self BG in flight? */
759 if (task
->actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) {
760 task_priority(task
, pri
, MAXPRI_USER
);
762 /* non embedded users need role for policy reapplication */
763 task
->role
= TASK_DEFAULT_APPLICATION
;
764 #endif /* CONFIG_EMBEDDED */
767 task
->actionstate
.hw_bg
= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
;
768 /* external BG in flight? */
769 if (task
->ext_actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
) {
770 task_priority(task
, pri
, MAXPRI_USER
);
772 /* non embedded users need role for policy reapplication */
773 task
->role
= TASK_DEFAULT_APPLICATION
;
774 #endif /* CONFIG_EMBEDDED */
784 /* restore the self backgrounding even if the thread is not current thread */
786 proc_restore_workq_bgthreadpolicy(thread_t thread
)
789 task_t wqtask
= TASK_NULL
;
791 if (thread
!= THREAD_NULL
) {
792 wqtask
= thread
->task
;
794 /* remove the background and restore default importance as self(internal) removal */
795 restore_bgthreadpolicy_locked(thread
, 1);
803 int proc_restore_bgthread_selfpolicy(void)
805 return(proc_restore_bgthreadpolicy(current_task(), thread_tid(current_thread())));
811 proc_restore_bgthreadpolicy(task_t task
, uint64_t tid
)
814 thread_t self
= current_thread();
815 thread_t thread
= THREAD_NULL
;
818 if (tid
== self
->thread_id
) {
822 thread
= task_findtid(task
, tid
);
826 restore_bgthreadpolicy_locked(thread
, selfset
);
837 restore_bgthreadpolicy_locked(thread_t thread
, int selfset
)
839 thread_precedence_policy_data_t policy
;
842 if (thread
!= NULL
) {
844 thread
->actionstate
.hw_bg
= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
;
845 /* external BG in flight? */
846 if (thread
->ext_actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
)
850 thread
->ext_actionstate
.hw_bg
= TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
;
851 /* self BG in flight? */
852 if (thread
->actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_NONE
)
857 /* reset thread priority (we did not save previous value) */
858 policy
.importance
= 0;
859 thread_policy_set_internal(thread
, THREAD_PRECEDENCE_POLICY
,
860 (thread_policy_t
)&policy
,
861 THREAD_PRECEDENCE_POLICY_COUNT
);
867 proc_set_task_apptype(task_t task
, int type
)
870 case PROC_POLICY_OSX_APPTYPE_TAL
:
871 task
->ext_policystate
.apptype
= type
;
872 task
->policystate
.apptype
= type
;
873 proc_apply_bgtaskpolicy_external(task
);
874 /* indicate that BG is set and next foreground needs to reset */
875 task
->ext_actionstate
.apptype
= type
;
878 case PROC_POLICY_OSX_APPTYPE_DBCLIENT
:
879 task
->ext_policystate
.apptype
= type
;
880 task
->policystate
.apptype
= type
;
881 proc_apply_bgtaskpolicy_internal(task
);
882 /* indicate that BG is set and next foreground needs to reset */
883 task
->ext_actionstate
.apptype
= type
;
886 case PROC_POLICY_IOS_APPTYPE
:
887 task
->ext_policystate
.apptype
= type
;
888 task
->policystate
.apptype
= type
;
890 case PROC_POLICY_IOS_NONUITYPE
:
891 task
->ext_policystate
.apptype
= type
;
892 task
->policystate
.apptype
= type
;
893 /* set to deny access to gpu */
894 task
->ext_actionstate
.hw_gpu
= TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
;
895 task
->ext_policystate
.hw_gpu
= TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
;
903 /* update the darwin backdground action state in the flags field for libproc */
904 #define PROC_FLAG_DARWINBG 0x8000 /* process in darwin background */
905 #define PROC_FLAG_EXT_DARWINBG 0x10000 /* process in darwin background - external enforcement */
908 proc_get_darwinbgstate(task_t task
, uint32_t * flagsp
)
910 if (task
->ext_actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_ALL
){
911 *flagsp
|= PROC_FLAG_EXT_DARWINBG
;
913 if (task
->actionstate
.hw_bg
== TASK_POLICY_BACKGROUND_ATTRIBUTE_ALL
){
914 *flagsp
|= PROC_FLAG_DARWINBG
;
921 * HW disk access realted routines, they need to return
922 * IOPOL_XXX equivalents for spec_xxx/throttle updates.
926 proc_get_task_disacc(task_t task
)
928 if ((task
->ext_actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
929 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
930 if (task
->ext_actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
931 return(task
->ext_actionstate
.hw_disk
);
932 if ((task
->actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
933 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
934 if (task
->actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
935 return(task
->actionstate
.hw_disk
);
936 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
);
940 proc_get_task_selfdiskacc(void)
942 task_t task
= current_task();
943 thread_t thread
= current_thread();
946 * As per defined iopolicysys behavior, thread trumps task.
947 * Do we need to follow that for external enforcements of BG or hw access?
948 * Status quo for now..
950 if((thread
->ext_actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
951 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
952 if (thread
->ext_actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
953 return(thread
->ext_actionstate
.hw_disk
);
954 if((thread
->actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
955 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
956 if (thread
->actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
957 return(thread
->actionstate
.hw_disk
);
959 if ((task
->ext_actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
960 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
961 if (task
->ext_actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
962 return(task
->ext_actionstate
.hw_disk
);
963 if ((task
->actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
964 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
965 if (task
->actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
966 return(task
->actionstate
.hw_disk
);
967 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
);
971 proc_get_thread_selfdiskacc(void)
973 thread_t thread
= current_thread();
975 if((thread
->ext_actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
976 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
977 if (thread
->ext_actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
978 return(thread
->ext_actionstate
.hw_disk
);
979 if((thread
->actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_DISKTHROTTLE
) != 0)
980 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_THROTTLE
);
981 if (thread
->actionstate
.hw_disk
!= TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
)
982 return(thread
->actionstate
.hw_disk
);
983 return(TASK_POLICY_HWACCESS_DISK_ATTRIBUTE_NORMAL
);
986 int proc_apply_task_diskacc(task_t task
, int policy
)
988 task_t self
= current_task();
992 task
->actionstate
.hw_disk
= policy
;
993 task
->policystate
.hw_disk
= policy
;
995 task
->ext_actionstate
.hw_disk
= policy
;
996 task
->ext_policystate
.hw_disk
= policy
;
1002 int proc_apply_thread_diskacc(task_t task
, uint64_t tid
, int policy
)
1006 if (tid
== TID_NULL
) {
1007 thread
= current_thread();
1008 proc_apply_thread_selfdiskacc(policy
);
1011 thread
= task_findtid(task
, tid
);
1012 if (thread
!= NULL
) {
1013 thread
->ext_actionstate
.hw_disk
= policy
;
1014 thread
->ext_policystate
.hw_disk
= policy
;
1025 proc_apply_thread_selfdiskacc(int policy
)
1027 task_t task
= current_task();
1028 thread_t thread
= current_thread();
1031 thread
->actionstate
.hw_disk
= policy
;
1032 thread
->policystate
.hw_disk
= policy
;
1038 proc_denyinherit_policy(__unused task_t task
)
1044 proc_denyselfset_policy(__unused task_t task
)
1049 /* HW GPU access related routines */
1051 proc_get_task_selfgpuacc_deny(void)
1053 task_t task
= current_task();
1054 thread_t thread
= current_thread();
1056 if (((task
->ext_actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_NOGPU
) != 0) || (task
->ext_actionstate
.hw_gpu
== TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
))
1057 return(TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
);
1058 if (((task
->actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_NOGPU
) != 0) || (task
->actionstate
.hw_gpu
== TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
))
1059 return(TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
);
1060 if (((thread
->ext_actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_NOGPU
) != 0) || (thread
->ext_actionstate
.hw_gpu
== TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
))
1061 return(TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
);
1062 if (((thread
->actionstate
.hw_bg
& TASK_POLICY_BACKGROUND_ATTRIBUTE_NOGPU
) != 0) || (thread
->actionstate
.hw_gpu
== TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
))
1063 return(TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NOACCESS
);
1065 return(TASK_POLICY_HWACCESS_GPU_ATTRIBUTE_NORMAL
);
1069 proc_apply_task_gpuacc(task_t task
, int policy
)
1072 task_t self
= current_task();
1076 task
->actionstate
.hw_gpu
= policy
;
1077 task
->policystate
.hw_gpu
= policy
;
1079 task
->ext_actionstate
.hw_gpu
= policy
;
1080 task
->ext_policystate
.hw_gpu
= policy
;
1087 /* Resource usage , CPU realted routines */
1089 proc_get_task_ruse_cpu(task_t task
, uint32_t * policyp
, uint32_t * percentagep
, uint64_t * intervalp
, uint64_t * deadlinep
)
1095 if (task
!= current_task()) {
1096 *policyp
= task
->ext_policystate
.ru_cpu
;
1098 *policyp
= task
->policystate
.ru_cpu
;
1101 error
= task_get_cpuusage(task
, percentagep
, intervalp
, deadlinep
);
1107 proc_set_task_ruse_cpu(task_t task
, uint32_t policy
, uint32_t percentage
, uint64_t interval
, uint64_t deadline
)
1112 if (task
!= current_task()) {
1113 task
->ext_policystate
.ru_cpu
= policy
;
1115 task
->policystate
.ru_cpu
= policy
;
1117 error
= task_set_cpuusage(task
, percentage
, interval
, deadline
);
1123 /* used to apply resource limit related actions */
1125 task_apply_resource_actions(task_t task
, int type
)
1127 int action
= TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
;
1128 void * bsdinfo
= NULL
;
1131 case TASK_POLICY_CPU_RESOURCE_USAGE
:
1133 case TASK_POLICY_WIREDMEM_RESOURCE_USAGE
:
1134 case TASK_POLICY_VIRTUALMEM_RESOURCE_USAGE
:
1135 case TASK_POLICY_DISK_RESOURCE_USAGE
:
1136 case TASK_POLICY_NETWORK_RESOURCE_USAGE
:
1137 case TASK_POLICY_POWER_RESOURCE_USAGE
:
1144 /* only cpu actions for now */
1147 if (task
->ext_actionstate
.ru_cpu
== TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
) {
1149 task
->ext_actionstate
.ru_cpu
= task
->ext_policystate
.ru_cpu
;
1150 action
= task
->ext_actionstate
.ru_cpu
;
1152 if (action
!= TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
) {
1153 bsdinfo
= task
->bsd_info
;
1155 proc_apply_resource_actions(bsdinfo
, TASK_POLICY_CPU_RESOURCE_USAGE
, action
);
1163 task_restore_resource_actions(task_t task
, int type
)
1166 void * bsdinfo
= NULL
;
1169 case TASK_POLICY_CPU_RESOURCE_USAGE
:
1171 case TASK_POLICY_WIREDMEM_RESOURCE_USAGE
:
1172 case TASK_POLICY_VIRTUALMEM_RESOURCE_USAGE
:
1173 case TASK_POLICY_DISK_RESOURCE_USAGE
:
1174 case TASK_POLICY_NETWORK_RESOURCE_USAGE
:
1175 case TASK_POLICY_POWER_RESOURCE_USAGE
:
1182 /* only cpu actions for now */
1185 action
= task
->ext_actionstate
.ru_cpu
;
1186 if (task
->ext_actionstate
.ru_cpu
!= TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
) {
1188 task
->ext_actionstate
.ru_cpu
= TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
;
1190 if (action
!= TASK_POLICY_RESOURCE_ATTRIBUTE_NONE
) {
1191 bsdinfo
= task
->bsd_info
;
1193 proc_restore_resource_actions(bsdinfo
, TASK_POLICY_CPU_RESOURCE_USAGE
, action
);
1201 /* For ledger hookups */
1203 task_get_cpuusage(__unused task_t task
, uint32_t * percentagep
, uint64_t * intervalp
, uint64_t * deadlinep
)
1213 task_set_cpuusage(__unused task_t task
, __unused
uint32_t percentage
, __unused
uint64_t interval
, __unused
uint64_t deadline
)
1218 /* called by ledger unit to enforce action due to resource usage criteria being met */
1220 task_action_cpuusage(task_t task
)
1222 return(task_apply_resource_actions(task
, TASK_POLICY_CPU_RESOURCE_USAGE
));
1226 proc_disable_task_apptype(task_t task
, int policy_subtype
)
1228 void * bsdinfo
= NULL
;
1231 int maxpri
= BASEPRI_DEFAULT
;
1235 if (task
->ext_policystate
.apptype
!= policy_subtype
) {
1240 #if !CONFIG_EMBEDDED
1241 switch (task
->role
) {
1242 case TASK_FOREGROUND_APPLICATION
:
1243 maxpri
= BASEPRI_FOREGROUND
;
1245 case TASK_BACKGROUND_APPLICATION
:
1246 maxpri
= BASEPRI_BACKGROUND
;
1249 maxpri
= BASEPRI_DEFAULT
;
1253 if (task
->ext_actionstate
.apptype
!= PROC_POLICY_OSX_APPTYPE_NONE
) {
1254 switch (task
->ext_actionstate
.apptype
) {
1255 case PROC_POLICY_OSX_APPTYPE_TAL
:
1256 /* disable foreground/background handling */
1257 task
->ext_actionstate
.apptype
= PROC_POLICY_OSX_APPTYPE_NONE
;
1258 /* external BG application removal */
1259 proc_restore_bgtaskpolicy_locked(task
, 1, 1, maxpri
);
1260 bsdinfo
= task
->bsd_info
;
1264 case PROC_POLICY_OSX_APPTYPE_DBCLIENT
:
1265 /* disable foreground/background handling */
1266 task
->ext_actionstate
.apptype
= PROC_POLICY_OSX_APPTYPE_NONE
;
1267 /* internal BG application removal */
1268 proc_restore_bgtaskpolicy_locked(task
, 1, 0, maxpri
);
1269 bsdinfo
= task
->bsd_info
;
1282 /* if backgrounding action ... */
1283 if (bsdinfo
!= NULL
)
1284 proc_set_task_networkbg(bsdinfo
, setbg
);
1290 proc_enable_task_apptype(task_t task
, int policy_subtype
)
1292 void * bsdinfo
= NULL
;
1298 if (task
->ext_policystate
.apptype
!= policy_subtype
) {
1303 if (task
->ext_actionstate
.apptype
== PROC_POLICY_OSX_APPTYPE_NONE
) {
1304 switch (task
->ext_policystate
.apptype
) {
1305 case PROC_POLICY_OSX_APPTYPE_TAL
:
1306 /* TAL policy is activated again */
1307 task
->ext_actionstate
.apptype
= task
->ext_policystate
.apptype
;
1308 if (task
->role
== TASK_BACKGROUND_APPLICATION
) {
1309 if (task
->role
== TASK_BACKGROUND_APPLICATION
) {
1310 proc_apply_bgtaskpolicy_locked(task
, 1, 1);
1311 bsdinfo
= task
->bsd_info
;
1325 /* if backgrounding action ... */
1326 if (bsdinfo
!= NULL
)
1327 proc_set_task_networkbg(bsdinfo
, setbg
);