1*2c2f96dcSApple OSS Distributions /*
2*2c2f96dcSApple OSS Distributions * Copyright (c) 2006-2018 Apple Inc. All rights reserved.
3*2c2f96dcSApple OSS Distributions *
4*2c2f96dcSApple OSS Distributions * @APPLE_LICENSE_HEADER_START@
5*2c2f96dcSApple OSS Distributions *
6*2c2f96dcSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*2c2f96dcSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*2c2f96dcSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*2c2f96dcSApple OSS Distributions * compliance with the License. Please obtain a copy of the License at
10*2c2f96dcSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this
11*2c2f96dcSApple OSS Distributions * file.
12*2c2f96dcSApple OSS Distributions *
13*2c2f96dcSApple OSS Distributions * The Original Code and all software distributed under the License are
14*2c2f96dcSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15*2c2f96dcSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16*2c2f96dcSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17*2c2f96dcSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18*2c2f96dcSApple OSS Distributions * Please see the License for the specific language governing rights and
19*2c2f96dcSApple OSS Distributions * limitations under the License.
20*2c2f96dcSApple OSS Distributions *
21*2c2f96dcSApple OSS Distributions * @APPLE_LICENSE_HEADER_END@
22*2c2f96dcSApple OSS Distributions */
23*2c2f96dcSApple OSS Distributions
24*2c2f96dcSApple OSS Distributions #include <sys/cdefs.h>
25*2c2f96dcSApple OSS Distributions #include <unistd.h>
26*2c2f96dcSApple OSS Distributions #include <errno.h>
27*2c2f96dcSApple OSS Distributions #include <string.h>
28*2c2f96dcSApple OSS Distributions #include <strings.h>
29*2c2f96dcSApple OSS Distributions #include <stdlib.h>
30*2c2f96dcSApple OSS Distributions #include <sys/errno.h>
31*2c2f96dcSApple OSS Distributions #include <sys/msgbuf.h>
32*2c2f96dcSApple OSS Distributions #include <sys/resource.h>
33*2c2f96dcSApple OSS Distributions #include <sys/process_policy.h>
34*2c2f96dcSApple OSS Distributions #include <sys/event.h>
35*2c2f96dcSApple OSS Distributions #include <mach/message.h>
36*2c2f96dcSApple OSS Distributions
37*2c2f96dcSApple OSS Distributions #include "libproc_internal.h"
38*2c2f96dcSApple OSS Distributions
39*2c2f96dcSApple OSS Distributions int __proc_info(int callnum, int pid, int flavor, uint64_t arg, void * buffer, int buffersize);
40*2c2f96dcSApple OSS Distributions int __proc_info_extended_id(int32_t callnum, int32_t pid, uint32_t flavor, uint32_t flags, uint64_t ext_id, uint64_t arg, user_addr_t buffer, int32_t buffersize);
41*2c2f96dcSApple OSS Distributions __private_extern__ int proc_setthreadname(void * buffer, int buffersize);
42*2c2f96dcSApple OSS Distributions int __process_policy(int scope, int action, int policy, int policy_subtype, proc_policy_attribute_t * attrp, pid_t target_pid, uint64_t target_threadid);
43*2c2f96dcSApple OSS Distributions int proc_rlimit_control(pid_t pid, int flavor, void *arg);
44*2c2f96dcSApple OSS Distributions
45*2c2f96dcSApple OSS Distributions int
proc_listpids(uint32_t type,uint32_t typeinfo,void * buffer,int buffersize)46*2c2f96dcSApple OSS Distributions proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize)
47*2c2f96dcSApple OSS Distributions {
48*2c2f96dcSApple OSS Distributions int retval;
49*2c2f96dcSApple OSS Distributions
50*2c2f96dcSApple OSS Distributions if ((type >= PROC_ALL_PIDS) || (type <= PROC_PPID_ONLY)) {
51*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_LISTPIDS, type, typeinfo, (uint64_t)0, buffer, buffersize)) == -1) {
52*2c2f96dcSApple OSS Distributions return 0;
53*2c2f96dcSApple OSS Distributions }
54*2c2f96dcSApple OSS Distributions } else {
55*2c2f96dcSApple OSS Distributions errno = EINVAL;
56*2c2f96dcSApple OSS Distributions retval = 0;
57*2c2f96dcSApple OSS Distributions }
58*2c2f96dcSApple OSS Distributions return retval;
59*2c2f96dcSApple OSS Distributions }
60*2c2f96dcSApple OSS Distributions
61*2c2f96dcSApple OSS Distributions
62*2c2f96dcSApple OSS Distributions int
proc_listallpids(void * buffer,int buffersize)63*2c2f96dcSApple OSS Distributions proc_listallpids(void * buffer, int buffersize)
64*2c2f96dcSApple OSS Distributions {
65*2c2f96dcSApple OSS Distributions int numpids;
66*2c2f96dcSApple OSS Distributions numpids = proc_listpids(PROC_ALL_PIDS, (uint32_t)0, buffer, buffersize);
67*2c2f96dcSApple OSS Distributions
68*2c2f96dcSApple OSS Distributions if (numpids == -1) {
69*2c2f96dcSApple OSS Distributions return -1;
70*2c2f96dcSApple OSS Distributions } else {
71*2c2f96dcSApple OSS Distributions return numpids / sizeof(int);
72*2c2f96dcSApple OSS Distributions }
73*2c2f96dcSApple OSS Distributions }
74*2c2f96dcSApple OSS Distributions
75*2c2f96dcSApple OSS Distributions int
proc_listpgrppids(pid_t pgrpid,void * buffer,int buffersize)76*2c2f96dcSApple OSS Distributions proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize)
77*2c2f96dcSApple OSS Distributions {
78*2c2f96dcSApple OSS Distributions int numpids;
79*2c2f96dcSApple OSS Distributions numpids = proc_listpids(PROC_PGRP_ONLY, (uint32_t)pgrpid, buffer, buffersize);
80*2c2f96dcSApple OSS Distributions if (numpids == -1) {
81*2c2f96dcSApple OSS Distributions return -1;
82*2c2f96dcSApple OSS Distributions } else {
83*2c2f96dcSApple OSS Distributions return numpids / sizeof(int);
84*2c2f96dcSApple OSS Distributions }
85*2c2f96dcSApple OSS Distributions }
86*2c2f96dcSApple OSS Distributions
87*2c2f96dcSApple OSS Distributions int
proc_listchildpids(pid_t ppid,void * buffer,int buffersize)88*2c2f96dcSApple OSS Distributions proc_listchildpids(pid_t ppid, void * buffer, int buffersize)
89*2c2f96dcSApple OSS Distributions {
90*2c2f96dcSApple OSS Distributions int numpids;
91*2c2f96dcSApple OSS Distributions numpids = proc_listpids(PROC_PPID_ONLY, (uint32_t)ppid, buffer, buffersize);
92*2c2f96dcSApple OSS Distributions if (numpids == -1) {
93*2c2f96dcSApple OSS Distributions return -1;
94*2c2f96dcSApple OSS Distributions } else {
95*2c2f96dcSApple OSS Distributions return numpids / sizeof(int);
96*2c2f96dcSApple OSS Distributions }
97*2c2f96dcSApple OSS Distributions }
98*2c2f96dcSApple OSS Distributions
99*2c2f96dcSApple OSS Distributions
100*2c2f96dcSApple OSS Distributions int
proc_pidinfo(int pid,int flavor,uint64_t arg,void * buffer,int buffersize)101*2c2f96dcSApple OSS Distributions proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize)
102*2c2f96dcSApple OSS Distributions {
103*2c2f96dcSApple OSS Distributions int retval;
104*2c2f96dcSApple OSS Distributions
105*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, flavor, arg, buffer, buffersize)) == -1) {
106*2c2f96dcSApple OSS Distributions return 0;
107*2c2f96dcSApple OSS Distributions }
108*2c2f96dcSApple OSS Distributions
109*2c2f96dcSApple OSS Distributions return retval;
110*2c2f96dcSApple OSS Distributions }
111*2c2f96dcSApple OSS Distributions
112*2c2f96dcSApple OSS Distributions
113*2c2f96dcSApple OSS Distributions int
proc_pidoriginatorinfo(int flavor,void * buffer,int buffersize)114*2c2f96dcSApple OSS Distributions proc_pidoriginatorinfo(int flavor, void *buffer, int buffersize)
115*2c2f96dcSApple OSS Distributions {
116*2c2f96dcSApple OSS Distributions int retval;
117*2c2f96dcSApple OSS Distributions
118*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_PIDORIGINATORINFO, getpid(), flavor, 0, buffer, buffersize)) == -1) {
119*2c2f96dcSApple OSS Distributions return 0;
120*2c2f96dcSApple OSS Distributions }
121*2c2f96dcSApple OSS Distributions
122*2c2f96dcSApple OSS Distributions return retval;
123*2c2f96dcSApple OSS Distributions }
124*2c2f96dcSApple OSS Distributions
125*2c2f96dcSApple OSS Distributions int
proc_listcoalitions(int flavor,int coaltype,void * buffer,int buffersize)126*2c2f96dcSApple OSS Distributions proc_listcoalitions(int flavor, int coaltype, void *buffer, int buffersize)
127*2c2f96dcSApple OSS Distributions {
128*2c2f96dcSApple OSS Distributions int retval;
129*2c2f96dcSApple OSS Distributions
130*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_LISTCOALITIONS, flavor, coaltype, 0, buffer, buffersize)) == -1) {
131*2c2f96dcSApple OSS Distributions return 0;
132*2c2f96dcSApple OSS Distributions }
133*2c2f96dcSApple OSS Distributions
134*2c2f96dcSApple OSS Distributions return retval;
135*2c2f96dcSApple OSS Distributions }
136*2c2f96dcSApple OSS Distributions
137*2c2f96dcSApple OSS Distributions int
proc_pid_rusage(int pid,int flavor,rusage_info_t * buffer)138*2c2f96dcSApple OSS Distributions proc_pid_rusage(int pid, int flavor, rusage_info_t *buffer)
139*2c2f96dcSApple OSS Distributions {
140*2c2f96dcSApple OSS Distributions return __proc_info(PROC_INFO_CALL_PIDRUSAGE, pid, flavor, 0, buffer, 0);
141*2c2f96dcSApple OSS Distributions }
142*2c2f96dcSApple OSS Distributions
143*2c2f96dcSApple OSS Distributions int
proc_setthread_cpupercent(uint8_t percentage,uint32_t ms_refill)144*2c2f96dcSApple OSS Distributions proc_setthread_cpupercent(uint8_t percentage, uint32_t ms_refill)
145*2c2f96dcSApple OSS Distributions {
146*2c2f96dcSApple OSS Distributions uint32_t arg = 0;
147*2c2f96dcSApple OSS Distributions
148*2c2f96dcSApple OSS Distributions /* Pack percentage and refill into a 32-bit number to match existing kernel implementation */
149*2c2f96dcSApple OSS Distributions if ((percentage >= 100) || (ms_refill & ~0xffffffU)) {
150*2c2f96dcSApple OSS Distributions errno = EINVAL;
151*2c2f96dcSApple OSS Distributions return -1;
152*2c2f96dcSApple OSS Distributions }
153*2c2f96dcSApple OSS Distributions
154*2c2f96dcSApple OSS Distributions arg = ((ms_refill << 8) | percentage);
155*2c2f96dcSApple OSS Distributions
156*2c2f96dcSApple OSS Distributions return proc_rlimit_control(-1, RLIMIT_THREAD_CPULIMITS, (void *)(uintptr_t)arg);
157*2c2f96dcSApple OSS Distributions }
158*2c2f96dcSApple OSS Distributions
159*2c2f96dcSApple OSS Distributions int
proc_pidfdinfo(int pid,int fd,int flavor,void * buffer,int buffersize)160*2c2f96dcSApple OSS Distributions proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize)
161*2c2f96dcSApple OSS Distributions {
162*2c2f96dcSApple OSS Distributions int retval;
163*2c2f96dcSApple OSS Distributions
164*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_PIDFDINFO, pid, flavor, (uint64_t)fd, buffer, buffersize)) == -1) {
165*2c2f96dcSApple OSS Distributions return 0;
166*2c2f96dcSApple OSS Distributions }
167*2c2f96dcSApple OSS Distributions
168*2c2f96dcSApple OSS Distributions return retval;
169*2c2f96dcSApple OSS Distributions }
170*2c2f96dcSApple OSS Distributions
171*2c2f96dcSApple OSS Distributions
172*2c2f96dcSApple OSS Distributions int
proc_pidfileportinfo(int pid,uint32_t fileport,int flavor,void * buffer,int buffersize)173*2c2f96dcSApple OSS Distributions proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize)
174*2c2f96dcSApple OSS Distributions {
175*2c2f96dcSApple OSS Distributions int retval;
176*2c2f96dcSApple OSS Distributions
177*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_PIDFILEPORTINFO, pid, flavor, (uint64_t)fileport, buffer, buffersize)) == -1) {
178*2c2f96dcSApple OSS Distributions return 0;
179*2c2f96dcSApple OSS Distributions }
180*2c2f96dcSApple OSS Distributions return retval;
181*2c2f96dcSApple OSS Distributions }
182*2c2f96dcSApple OSS Distributions
183*2c2f96dcSApple OSS Distributions int
proc_piddynkqueueinfo(int pid,int flavor,kqueue_id_t kq_id,void * buffer,int buffersize)184*2c2f96dcSApple OSS Distributions proc_piddynkqueueinfo(int pid, int flavor, kqueue_id_t kq_id, void *buffer, int buffersize)
185*2c2f96dcSApple OSS Distributions {
186*2c2f96dcSApple OSS Distributions int ret;
187*2c2f96dcSApple OSS Distributions
188*2c2f96dcSApple OSS Distributions if ((ret = __proc_info(PROC_INFO_CALL_PIDDYNKQUEUEINFO, pid, flavor, (uint64_t)kq_id, buffer, buffersize)) == -1) {
189*2c2f96dcSApple OSS Distributions return 0;
190*2c2f96dcSApple OSS Distributions }
191*2c2f96dcSApple OSS Distributions
192*2c2f96dcSApple OSS Distributions return ret;
193*2c2f96dcSApple OSS Distributions }
194*2c2f96dcSApple OSS Distributions
195*2c2f96dcSApple OSS Distributions int
proc_udata_info(int pid,int flavor,void * buffer,int buffersize)196*2c2f96dcSApple OSS Distributions proc_udata_info(int pid, int flavor, void *buffer, int buffersize)
197*2c2f96dcSApple OSS Distributions {
198*2c2f96dcSApple OSS Distributions return __proc_info(PROC_INFO_CALL_UDATA_INFO, pid, flavor, 0, buffer, buffersize);
199*2c2f96dcSApple OSS Distributions }
200*2c2f96dcSApple OSS Distributions
201*2c2f96dcSApple OSS Distributions /* only used by dyld which links with libsystem_kernel.a */
202*2c2f96dcSApple OSS Distributions __private_extern__ int
proc_set_dyld_all_image_info(void * buffer,int buffersize)203*2c2f96dcSApple OSS Distributions proc_set_dyld_all_image_info(void *buffer, int buffersize)
204*2c2f96dcSApple OSS Distributions {
205*2c2f96dcSApple OSS Distributions return __proc_info(PROC_INFO_CALL_SET_DYLD_IMAGES, getpid(), 0, 0, buffer, buffersize);
206*2c2f96dcSApple OSS Distributions }
207*2c2f96dcSApple OSS Distributions
208*2c2f96dcSApple OSS Distributions
209*2c2f96dcSApple OSS Distributions int
proc_name(int pid,void * buffer,uint32_t buffersize)210*2c2f96dcSApple OSS Distributions proc_name(int pid, void * buffer, uint32_t buffersize)
211*2c2f96dcSApple OSS Distributions {
212*2c2f96dcSApple OSS Distributions int retval = 0, len;
213*2c2f96dcSApple OSS Distributions struct proc_bsdinfo pbsd;
214*2c2f96dcSApple OSS Distributions
215*2c2f96dcSApple OSS Distributions
216*2c2f96dcSApple OSS Distributions if (buffersize < sizeof(pbsd.pbi_name)) {
217*2c2f96dcSApple OSS Distributions errno = ENOMEM;
218*2c2f96dcSApple OSS Distributions return 0;
219*2c2f96dcSApple OSS Distributions }
220*2c2f96dcSApple OSS Distributions
221*2c2f96dcSApple OSS Distributions retval = proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &pbsd, sizeof(struct proc_bsdinfo));
222*2c2f96dcSApple OSS Distributions if (retval != 0) {
223*2c2f96dcSApple OSS Distributions if (pbsd.pbi_name[0]) {
224*2c2f96dcSApple OSS Distributions bcopy(&pbsd.pbi_name, buffer, sizeof(pbsd.pbi_name));
225*2c2f96dcSApple OSS Distributions } else {
226*2c2f96dcSApple OSS Distributions bcopy(&pbsd.pbi_comm, buffer, sizeof(pbsd.pbi_comm));
227*2c2f96dcSApple OSS Distributions }
228*2c2f96dcSApple OSS Distributions len = (int)strlen(buffer);
229*2c2f96dcSApple OSS Distributions return len;
230*2c2f96dcSApple OSS Distributions }
231*2c2f96dcSApple OSS Distributions return 0;
232*2c2f96dcSApple OSS Distributions }
233*2c2f96dcSApple OSS Distributions
234*2c2f96dcSApple OSS Distributions int
proc_regionfilename(int pid,uint64_t address,void * buffer,uint32_t buffersize)235*2c2f96dcSApple OSS Distributions proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize)
236*2c2f96dcSApple OSS Distributions {
237*2c2f96dcSApple OSS Distributions int retval;
238*2c2f96dcSApple OSS Distributions struct proc_regionpath path;
239*2c2f96dcSApple OSS Distributions
240*2c2f96dcSApple OSS Distributions if (buffersize < MAXPATHLEN) {
241*2c2f96dcSApple OSS Distributions errno = ENOMEM;
242*2c2f96dcSApple OSS Distributions return 0;
243*2c2f96dcSApple OSS Distributions }
244*2c2f96dcSApple OSS Distributions
245*2c2f96dcSApple OSS Distributions retval = proc_pidinfo(pid, PROC_PIDREGIONPATH, (uint64_t)address, &path, sizeof(struct proc_regionpath));
246*2c2f96dcSApple OSS Distributions if (retval != 0) {
247*2c2f96dcSApple OSS Distributions return (int)(strlcpy(buffer, path.prpo_path, buffersize));
248*2c2f96dcSApple OSS Distributions }
249*2c2f96dcSApple OSS Distributions return 0;
250*2c2f96dcSApple OSS Distributions }
251*2c2f96dcSApple OSS Distributions
252*2c2f96dcSApple OSS Distributions int
proc_kmsgbuf(void * buffer,uint32_t buffersize)253*2c2f96dcSApple OSS Distributions proc_kmsgbuf(void * buffer, uint32_t buffersize)
254*2c2f96dcSApple OSS Distributions {
255*2c2f96dcSApple OSS Distributions int retval;
256*2c2f96dcSApple OSS Distributions
257*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_KERNMSGBUF, 0, 0, (uint64_t)0, buffer, buffersize)) == -1) {
258*2c2f96dcSApple OSS Distributions return 0;
259*2c2f96dcSApple OSS Distributions }
260*2c2f96dcSApple OSS Distributions return retval;
261*2c2f96dcSApple OSS Distributions }
262*2c2f96dcSApple OSS Distributions
263*2c2f96dcSApple OSS Distributions int
proc_pidpath(int pid,void * buffer,uint32_t buffersize)264*2c2f96dcSApple OSS Distributions proc_pidpath(int pid, void * buffer, uint32_t buffersize)
265*2c2f96dcSApple OSS Distributions {
266*2c2f96dcSApple OSS Distributions int retval, len;
267*2c2f96dcSApple OSS Distributions
268*2c2f96dcSApple OSS Distributions if (buffersize < PROC_PIDPATHINFO_SIZE) {
269*2c2f96dcSApple OSS Distributions errno = ENOMEM;
270*2c2f96dcSApple OSS Distributions return 0;
271*2c2f96dcSApple OSS Distributions }
272*2c2f96dcSApple OSS Distributions if (buffersize > PROC_PIDPATHINFO_MAXSIZE) {
273*2c2f96dcSApple OSS Distributions errno = EOVERFLOW;
274*2c2f96dcSApple OSS Distributions return 0;
275*2c2f96dcSApple OSS Distributions }
276*2c2f96dcSApple OSS Distributions
277*2c2f96dcSApple OSS Distributions retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDPATHINFO, (uint64_t)0, buffer, buffersize);
278*2c2f96dcSApple OSS Distributions if (retval != -1) {
279*2c2f96dcSApple OSS Distributions len = (int)strlen(buffer);
280*2c2f96dcSApple OSS Distributions return len;
281*2c2f96dcSApple OSS Distributions }
282*2c2f96dcSApple OSS Distributions return 0;
283*2c2f96dcSApple OSS Distributions }
284*2c2f96dcSApple OSS Distributions
285*2c2f96dcSApple OSS Distributions int
proc_pidpath_audittoken(audit_token_t * audittoken,void * buffer,uint32_t buffersize)286*2c2f96dcSApple OSS Distributions proc_pidpath_audittoken(audit_token_t *audittoken, void * buffer, uint32_t buffersize)
287*2c2f96dcSApple OSS Distributions {
288*2c2f96dcSApple OSS Distributions int retval, len;
289*2c2f96dcSApple OSS Distributions
290*2c2f96dcSApple OSS Distributions if (buffersize < PROC_PIDPATHINFO_SIZE) {
291*2c2f96dcSApple OSS Distributions errno = ENOMEM;
292*2c2f96dcSApple OSS Distributions return 0;
293*2c2f96dcSApple OSS Distributions }
294*2c2f96dcSApple OSS Distributions if (buffersize > PROC_PIDPATHINFO_MAXSIZE) {
295*2c2f96dcSApple OSS Distributions errno = EOVERFLOW;
296*2c2f96dcSApple OSS Distributions return 0;
297*2c2f96dcSApple OSS Distributions }
298*2c2f96dcSApple OSS Distributions
299*2c2f96dcSApple OSS Distributions int pid = audittoken->val[5];
300*2c2f96dcSApple OSS Distributions int idversion = audittoken->val[7];
301*2c2f96dcSApple OSS Distributions
302*2c2f96dcSApple OSS Distributions retval = __proc_info_extended_id(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDPATHINFO, PIF_COMPARE_IDVERSION, (uint64_t)idversion,
303*2c2f96dcSApple OSS Distributions (uint64_t)0, buffer, buffersize);
304*2c2f96dcSApple OSS Distributions if (retval != -1) {
305*2c2f96dcSApple OSS Distributions len = (int)strlen(buffer);
306*2c2f96dcSApple OSS Distributions return len;
307*2c2f96dcSApple OSS Distributions }
308*2c2f96dcSApple OSS Distributions return 0;
309*2c2f96dcSApple OSS Distributions }
310*2c2f96dcSApple OSS Distributions
311*2c2f96dcSApple OSS Distributions int
proc_current_thread_schedinfo(void * buffer,size_t buffersize)312*2c2f96dcSApple OSS Distributions proc_current_thread_schedinfo(void *buffer, size_t buffersize)
313*2c2f96dcSApple OSS Distributions {
314*2c2f96dcSApple OSS Distributions extern uint64_t __thread_selfid(void);
315*2c2f96dcSApple OSS Distributions
316*2c2f96dcSApple OSS Distributions int retval;
317*2c2f96dcSApple OSS Distributions
318*2c2f96dcSApple OSS Distributions if (buffersize < PROC_PIDTHREADSCHEDINFO_SIZE) {
319*2c2f96dcSApple OSS Distributions errno = ENOMEM;
320*2c2f96dcSApple OSS Distributions return errno;
321*2c2f96dcSApple OSS Distributions }
322*2c2f96dcSApple OSS Distributions if (buffersize > PROC_PIDTHREADSCHEDINFO_SIZE) {
323*2c2f96dcSApple OSS Distributions errno = EOVERFLOW;
324*2c2f96dcSApple OSS Distributions return errno;
325*2c2f96dcSApple OSS Distributions }
326*2c2f96dcSApple OSS Distributions
327*2c2f96dcSApple OSS Distributions pid_t pid = getpid();
328*2c2f96dcSApple OSS Distributions uint64_t threadid = __thread_selfid();
329*2c2f96dcSApple OSS Distributions
330*2c2f96dcSApple OSS Distributions retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDTHREADSCHEDINFO, threadid, buffer, buffersize);
331*2c2f96dcSApple OSS Distributions
332*2c2f96dcSApple OSS Distributions if (retval == -1) {
333*2c2f96dcSApple OSS Distributions return errno;
334*2c2f96dcSApple OSS Distributions }
335*2c2f96dcSApple OSS Distributions return 0;
336*2c2f96dcSApple OSS Distributions }
337*2c2f96dcSApple OSS Distributions
338*2c2f96dcSApple OSS Distributions int
proc_libversion(int * major,int * minor)339*2c2f96dcSApple OSS Distributions proc_libversion(int *major, int * minor)
340*2c2f96dcSApple OSS Distributions {
341*2c2f96dcSApple OSS Distributions if (major != NULL) {
342*2c2f96dcSApple OSS Distributions *major = 1;
343*2c2f96dcSApple OSS Distributions }
344*2c2f96dcSApple OSS Distributions if (minor != NULL) {
345*2c2f96dcSApple OSS Distributions *minor = 1;
346*2c2f96dcSApple OSS Distributions }
347*2c2f96dcSApple OSS Distributions return 0;
348*2c2f96dcSApple OSS Distributions }
349*2c2f96dcSApple OSS Distributions
350*2c2f96dcSApple OSS Distributions int
proc_setpcontrol(const int control)351*2c2f96dcSApple OSS Distributions proc_setpcontrol(const int control)
352*2c2f96dcSApple OSS Distributions {
353*2c2f96dcSApple OSS Distributions int retval;
354*2c2f96dcSApple OSS Distributions
355*2c2f96dcSApple OSS Distributions if (control < PROC_SETPC_NONE || control > PROC_SETPC_TERMINATE) {
356*2c2f96dcSApple OSS Distributions return EINVAL;
357*2c2f96dcSApple OSS Distributions }
358*2c2f96dcSApple OSS Distributions
359*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_PCONTROL, (uint64_t)control, NULL, 0)) == -1) {
360*2c2f96dcSApple OSS Distributions return errno;
361*2c2f96dcSApple OSS Distributions }
362*2c2f96dcSApple OSS Distributions
363*2c2f96dcSApple OSS Distributions return 0;
364*2c2f96dcSApple OSS Distributions }
365*2c2f96dcSApple OSS Distributions
366*2c2f96dcSApple OSS Distributions
367*2c2f96dcSApple OSS Distributions __private_extern__ int
proc_setthreadname(void * buffer,int buffersize)368*2c2f96dcSApple OSS Distributions proc_setthreadname(void * buffer, int buffersize)
369*2c2f96dcSApple OSS Distributions {
370*2c2f96dcSApple OSS Distributions int retval;
371*2c2f96dcSApple OSS Distributions
372*2c2f96dcSApple OSS Distributions retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_THREADNAME, (uint64_t)0, buffer, buffersize);
373*2c2f96dcSApple OSS Distributions
374*2c2f96dcSApple OSS Distributions if (retval == -1) {
375*2c2f96dcSApple OSS Distributions return errno;
376*2c2f96dcSApple OSS Distributions } else {
377*2c2f96dcSApple OSS Distributions return 0;
378*2c2f96dcSApple OSS Distributions }
379*2c2f96dcSApple OSS Distributions }
380*2c2f96dcSApple OSS Distributions
381*2c2f96dcSApple OSS Distributions int
proc_track_dirty(pid_t pid,uint32_t flags)382*2c2f96dcSApple OSS Distributions proc_track_dirty(pid_t pid, uint32_t flags)
383*2c2f96dcSApple OSS Distributions {
384*2c2f96dcSApple OSS Distributions if (__proc_info(PROC_INFO_CALL_DIRTYCONTROL, pid, PROC_DIRTYCONTROL_TRACK, flags, NULL, 0) == -1) {
385*2c2f96dcSApple OSS Distributions return errno;
386*2c2f96dcSApple OSS Distributions }
387*2c2f96dcSApple OSS Distributions
388*2c2f96dcSApple OSS Distributions return 0;
389*2c2f96dcSApple OSS Distributions }
390*2c2f96dcSApple OSS Distributions
391*2c2f96dcSApple OSS Distributions int
proc_set_dirty(pid_t pid,bool dirty)392*2c2f96dcSApple OSS Distributions proc_set_dirty(pid_t pid, bool dirty)
393*2c2f96dcSApple OSS Distributions {
394*2c2f96dcSApple OSS Distributions if (__proc_info(PROC_INFO_CALL_DIRTYCONTROL, pid, PROC_DIRTYCONTROL_SET, dirty, NULL, 0) == -1) {
395*2c2f96dcSApple OSS Distributions return errno;
396*2c2f96dcSApple OSS Distributions }
397*2c2f96dcSApple OSS Distributions
398*2c2f96dcSApple OSS Distributions return 0;
399*2c2f96dcSApple OSS Distributions }
400*2c2f96dcSApple OSS Distributions
401*2c2f96dcSApple OSS Distributions int
proc_get_dirty(pid_t pid,uint32_t * flags)402*2c2f96dcSApple OSS Distributions proc_get_dirty(pid_t pid, uint32_t *flags)
403*2c2f96dcSApple OSS Distributions {
404*2c2f96dcSApple OSS Distributions int retval;
405*2c2f96dcSApple OSS Distributions
406*2c2f96dcSApple OSS Distributions if (!flags) {
407*2c2f96dcSApple OSS Distributions return EINVAL;
408*2c2f96dcSApple OSS Distributions }
409*2c2f96dcSApple OSS Distributions
410*2c2f96dcSApple OSS Distributions retval = __proc_info(PROC_INFO_CALL_DIRTYCONTROL, pid, PROC_DIRTYCONTROL_GET, 0, NULL, 0);
411*2c2f96dcSApple OSS Distributions if (retval == -1) {
412*2c2f96dcSApple OSS Distributions return errno;
413*2c2f96dcSApple OSS Distributions }
414*2c2f96dcSApple OSS Distributions
415*2c2f96dcSApple OSS Distributions *flags = retval;
416*2c2f96dcSApple OSS Distributions
417*2c2f96dcSApple OSS Distributions return 0;
418*2c2f96dcSApple OSS Distributions }
419*2c2f96dcSApple OSS Distributions
420*2c2f96dcSApple OSS Distributions int
proc_clear_dirty(pid_t pid,uint32_t flags)421*2c2f96dcSApple OSS Distributions proc_clear_dirty(pid_t pid, uint32_t flags)
422*2c2f96dcSApple OSS Distributions {
423*2c2f96dcSApple OSS Distributions if (__proc_info(PROC_INFO_CALL_DIRTYCONTROL, pid, PROC_DIRTYCONTROL_CLEAR, flags, NULL, 0) == -1) {
424*2c2f96dcSApple OSS Distributions return errno;
425*2c2f96dcSApple OSS Distributions }
426*2c2f96dcSApple OSS Distributions
427*2c2f96dcSApple OSS Distributions return 0;
428*2c2f96dcSApple OSS Distributions }
429*2c2f96dcSApple OSS Distributions
430*2c2f96dcSApple OSS Distributions int
proc_terminate(pid_t pid,int * sig)431*2c2f96dcSApple OSS Distributions proc_terminate(pid_t pid, int *sig)
432*2c2f96dcSApple OSS Distributions {
433*2c2f96dcSApple OSS Distributions int retval;
434*2c2f96dcSApple OSS Distributions
435*2c2f96dcSApple OSS Distributions if (!sig) {
436*2c2f96dcSApple OSS Distributions return EINVAL;
437*2c2f96dcSApple OSS Distributions }
438*2c2f96dcSApple OSS Distributions
439*2c2f96dcSApple OSS Distributions retval = __proc_info(PROC_INFO_CALL_TERMINATE, pid, 0, 0, NULL, 0);
440*2c2f96dcSApple OSS Distributions if (retval == -1) {
441*2c2f96dcSApple OSS Distributions return errno;
442*2c2f96dcSApple OSS Distributions }
443*2c2f96dcSApple OSS Distributions
444*2c2f96dcSApple OSS Distributions *sig = retval;
445*2c2f96dcSApple OSS Distributions
446*2c2f96dcSApple OSS Distributions return 0;
447*2c2f96dcSApple OSS Distributions }
448*2c2f96dcSApple OSS Distributions
449*2c2f96dcSApple OSS Distributions int
proc_signal_with_audittoken(audit_token_t * audittoken,int sig)450*2c2f96dcSApple OSS Distributions proc_signal_with_audittoken(audit_token_t *audittoken, int sig)
451*2c2f96dcSApple OSS Distributions {
452*2c2f96dcSApple OSS Distributions int retval = __proc_info(PROC_INFO_CALL_SIGNAL_AUDITTOKEN, 0, sig, 0, audittoken, 0);
453*2c2f96dcSApple OSS Distributions if (retval == -1) {
454*2c2f96dcSApple OSS Distributions return errno;
455*2c2f96dcSApple OSS Distributions }
456*2c2f96dcSApple OSS Distributions
457*2c2f96dcSApple OSS Distributions return 0;
458*2c2f96dcSApple OSS Distributions }
459*2c2f96dcSApple OSS Distributions
460*2c2f96dcSApple OSS Distributions int
proc_terminate_with_audittoken(audit_token_t * audittoken,int * sig)461*2c2f96dcSApple OSS Distributions proc_terminate_with_audittoken(audit_token_t *audittoken, int *sig)
462*2c2f96dcSApple OSS Distributions {
463*2c2f96dcSApple OSS Distributions int retval;
464*2c2f96dcSApple OSS Distributions
465*2c2f96dcSApple OSS Distributions if (!sig) {
466*2c2f96dcSApple OSS Distributions return EINVAL;
467*2c2f96dcSApple OSS Distributions }
468*2c2f96dcSApple OSS Distributions
469*2c2f96dcSApple OSS Distributions retval = __proc_info(PROC_INFO_CALL_TERMINATE_AUDITTOKEN, 0, 0, 0, audittoken, 0);
470*2c2f96dcSApple OSS Distributions if (retval == -1) {
471*2c2f96dcSApple OSS Distributions return errno;
472*2c2f96dcSApple OSS Distributions }
473*2c2f96dcSApple OSS Distributions
474*2c2f96dcSApple OSS Distributions *sig = retval;
475*2c2f96dcSApple OSS Distributions
476*2c2f96dcSApple OSS Distributions return 0;
477*2c2f96dcSApple OSS Distributions }
478*2c2f96dcSApple OSS Distributions
479*2c2f96dcSApple OSS Distributions int
proc_terminate_all_rsr(int sig)480*2c2f96dcSApple OSS Distributions proc_terminate_all_rsr(int sig)
481*2c2f96dcSApple OSS Distributions {
482*2c2f96dcSApple OSS Distributions int retval = 0;
483*2c2f96dcSApple OSS Distributions
484*2c2f96dcSApple OSS Distributions if (sig != SIGKILL && sig != SIGTERM) {
485*2c2f96dcSApple OSS Distributions return EINVAL;
486*2c2f96dcSApple OSS Distributions }
487*2c2f96dcSApple OSS Distributions
488*2c2f96dcSApple OSS Distributions retval = __proc_info(PROC_INFO_CALL_TERMINATE_RSR, 0, 0, sig, NULL, 0);
489*2c2f96dcSApple OSS Distributions if (retval == -1) {
490*2c2f96dcSApple OSS Distributions return errno;
491*2c2f96dcSApple OSS Distributions }
492*2c2f96dcSApple OSS Distributions
493*2c2f96dcSApple OSS Distributions return 0;
494*2c2f96dcSApple OSS Distributions }
495*2c2f96dcSApple OSS Distributions
496*2c2f96dcSApple OSS Distributions /*
497*2c2f96dcSApple OSS Distributions * XXX the _fatal() variant both checks for an existing monitor
498*2c2f96dcSApple OSS Distributions * (with important policy effects on first party background apps)
499*2c2f96dcSApple OSS Distributions * and validates inputs.
500*2c2f96dcSApple OSS Distributions */
501*2c2f96dcSApple OSS Distributions int
proc_set_cpumon_params(pid_t pid,int percentage,int interval)502*2c2f96dcSApple OSS Distributions proc_set_cpumon_params(pid_t pid, int percentage, int interval)
503*2c2f96dcSApple OSS Distributions {
504*2c2f96dcSApple OSS Distributions proc_policy_cpuusage_attr_t attr;
505*2c2f96dcSApple OSS Distributions
506*2c2f96dcSApple OSS Distributions /* no argument validation ...
507*2c2f96dcSApple OSS Distributions * task_set_cpuusage() ignores 0 values and squashes negative
508*2c2f96dcSApple OSS Distributions * values into uint32_t.
509*2c2f96dcSApple OSS Distributions */
510*2c2f96dcSApple OSS Distributions
511*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC;
512*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_percentage = percentage;
513*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_interval = (uint64_t)interval;
514*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_deadline = 0;
515*2c2f96dcSApple OSS Distributions
516*2c2f96dcSApple OSS Distributions return __process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_SET, PROC_POLICY_RESOURCE_USAGE,
517*2c2f96dcSApple OSS Distributions PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0);
518*2c2f96dcSApple OSS Distributions }
519*2c2f96dcSApple OSS Distributions
520*2c2f96dcSApple OSS Distributions int
proc_get_cpumon_params(pid_t pid,int * percentage,int * interval)521*2c2f96dcSApple OSS Distributions proc_get_cpumon_params(pid_t pid, int *percentage, int *interval)
522*2c2f96dcSApple OSS Distributions {
523*2c2f96dcSApple OSS Distributions proc_policy_cpuusage_attr_t attr;
524*2c2f96dcSApple OSS Distributions int ret;
525*2c2f96dcSApple OSS Distributions
526*2c2f96dcSApple OSS Distributions ret = __process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_GET, PROC_POLICY_RESOURCE_USAGE,
527*2c2f96dcSApple OSS Distributions PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0);
528*2c2f96dcSApple OSS Distributions
529*2c2f96dcSApple OSS Distributions if ((ret == 0) && (attr.ppattr_cpu_attr == PROC_POLICY_RSRCACT_NOTIFY_EXC)) {
530*2c2f96dcSApple OSS Distributions *percentage = attr.ppattr_cpu_percentage;
531*2c2f96dcSApple OSS Distributions *interval = (int)attr.ppattr_cpu_attr_interval;
532*2c2f96dcSApple OSS Distributions } else {
533*2c2f96dcSApple OSS Distributions *percentage = 0;
534*2c2f96dcSApple OSS Distributions *interval = 0;
535*2c2f96dcSApple OSS Distributions }
536*2c2f96dcSApple OSS Distributions
537*2c2f96dcSApple OSS Distributions return ret;
538*2c2f96dcSApple OSS Distributions }
539*2c2f96dcSApple OSS Distributions
540*2c2f96dcSApple OSS Distributions int
proc_set_cpumon_defaults(pid_t pid)541*2c2f96dcSApple OSS Distributions proc_set_cpumon_defaults(pid_t pid)
542*2c2f96dcSApple OSS Distributions {
543*2c2f96dcSApple OSS Distributions proc_policy_cpuusage_attr_t attr;
544*2c2f96dcSApple OSS Distributions
545*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC;
546*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_percentage = PROC_POLICY_CPUMON_DEFAULTS;
547*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_interval = 0;
548*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_deadline = 0;
549*2c2f96dcSApple OSS Distributions
550*2c2f96dcSApple OSS Distributions return __process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_SET, PROC_POLICY_RESOURCE_USAGE,
551*2c2f96dcSApple OSS Distributions PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0);
552*2c2f96dcSApple OSS Distributions }
553*2c2f96dcSApple OSS Distributions
554*2c2f96dcSApple OSS Distributions int
proc_resume_cpumon(pid_t pid)555*2c2f96dcSApple OSS Distributions proc_resume_cpumon(pid_t pid)
556*2c2f96dcSApple OSS Distributions {
557*2c2f96dcSApple OSS Distributions return __process_policy(PROC_POLICY_SCOPE_PROCESS,
558*2c2f96dcSApple OSS Distributions PROC_POLICY_ACTION_ENABLE,
559*2c2f96dcSApple OSS Distributions PROC_POLICY_RESOURCE_USAGE,
560*2c2f96dcSApple OSS Distributions PROC_POLICY_RUSAGE_CPU,
561*2c2f96dcSApple OSS Distributions NULL, pid, 0);
562*2c2f96dcSApple OSS Distributions }
563*2c2f96dcSApple OSS Distributions
564*2c2f96dcSApple OSS Distributions int
proc_disable_cpumon(pid_t pid)565*2c2f96dcSApple OSS Distributions proc_disable_cpumon(pid_t pid)
566*2c2f96dcSApple OSS Distributions {
567*2c2f96dcSApple OSS Distributions proc_policy_cpuusage_attr_t attr;
568*2c2f96dcSApple OSS Distributions
569*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC;
570*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_percentage = PROC_POLICY_CPUMON_DISABLE;
571*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_interval = 0;
572*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_deadline = 0;
573*2c2f96dcSApple OSS Distributions
574*2c2f96dcSApple OSS Distributions return __process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_SET, PROC_POLICY_RESOURCE_USAGE,
575*2c2f96dcSApple OSS Distributions PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0);
576*2c2f96dcSApple OSS Distributions }
577*2c2f96dcSApple OSS Distributions
578*2c2f96dcSApple OSS Distributions
579*2c2f96dcSApple OSS Distributions /*
580*2c2f96dcSApple OSS Distributions * Turn on the CPU usage monitor using the supplied parameters, and make
581*2c2f96dcSApple OSS Distributions * violations of the monitor fatal.
582*2c2f96dcSApple OSS Distributions *
583*2c2f96dcSApple OSS Distributions * Returns: 0 on success;
584*2c2f96dcSApple OSS Distributions * -1 on failure and sets errno
585*2c2f96dcSApple OSS Distributions */
586*2c2f96dcSApple OSS Distributions int
proc_set_cpumon_params_fatal(pid_t pid,int percentage,int interval)587*2c2f96dcSApple OSS Distributions proc_set_cpumon_params_fatal(pid_t pid, int percentage, int interval)
588*2c2f96dcSApple OSS Distributions {
589*2c2f96dcSApple OSS Distributions int current_percentage = 0;
590*2c2f96dcSApple OSS Distributions int current_interval = 0; /* intervals are in seconds */
591*2c2f96dcSApple OSS Distributions int ret = 0;
592*2c2f96dcSApple OSS Distributions
593*2c2f96dcSApple OSS Distributions if ((percentage <= 0) || (interval <= 0)) {
594*2c2f96dcSApple OSS Distributions errno = EINVAL;
595*2c2f96dcSApple OSS Distributions return -1;
596*2c2f96dcSApple OSS Distributions }
597*2c2f96dcSApple OSS Distributions
598*2c2f96dcSApple OSS Distributions /*
599*2c2f96dcSApple OSS Distributions * Do a simple query to see if CPU monitoring is
600*2c2f96dcSApple OSS Distributions * already active. If either the percentage or the
601*2c2f96dcSApple OSS Distributions * interval is nonzero, then CPU monitoring is
602*2c2f96dcSApple OSS Distributions * already in use for this process.
603*2c2f96dcSApple OSS Distributions *
604*2c2f96dcSApple OSS Distributions * XXX: need set...() and set..fatal() to behave similarly.
605*2c2f96dcSApple OSS Distributions * Currently, this check prevents 1st party apps (which get a
606*2c2f96dcSApple OSS Distributions * default non-fatal monitor) not to get a fatal monitor.
607*2c2f96dcSApple OSS Distributions */
608*2c2f96dcSApple OSS Distributions (void)proc_get_cpumon_params(pid, ¤t_percentage, ¤t_interval);
609*2c2f96dcSApple OSS Distributions if (current_percentage || current_interval) {
610*2c2f96dcSApple OSS Distributions /*
611*2c2f96dcSApple OSS Distributions * The CPU monitor appears to be active.
612*2c2f96dcSApple OSS Distributions * We choose not to disturb those settings.
613*2c2f96dcSApple OSS Distributions */
614*2c2f96dcSApple OSS Distributions errno = EBUSY;
615*2c2f96dcSApple OSS Distributions return -1;
616*2c2f96dcSApple OSS Distributions }
617*2c2f96dcSApple OSS Distributions
618*2c2f96dcSApple OSS Distributions if ((ret = proc_set_cpumon_params(pid, percentage, interval)) != 0) {
619*2c2f96dcSApple OSS Distributions /* Failed to activate the CPU monitor */
620*2c2f96dcSApple OSS Distributions return ret;
621*2c2f96dcSApple OSS Distributions }
622*2c2f96dcSApple OSS Distributions
623*2c2f96dcSApple OSS Distributions if ((ret = proc_rlimit_control(pid, RLIMIT_CPU_USAGE_MONITOR, (void *)(uintptr_t)CPUMON_MAKE_FATAL)) != 0) {
624*2c2f96dcSApple OSS Distributions /* Failed to set termination, back out the CPU monitor settings. */
625*2c2f96dcSApple OSS Distributions (void)proc_disable_cpumon(pid);
626*2c2f96dcSApple OSS Distributions }
627*2c2f96dcSApple OSS Distributions
628*2c2f96dcSApple OSS Distributions return ret;
629*2c2f96dcSApple OSS Distributions }
630*2c2f96dcSApple OSS Distributions
631*2c2f96dcSApple OSS Distributions int
proc_set_wakemon_params(pid_t pid,int rate_hz,int flags __unused)632*2c2f96dcSApple OSS Distributions proc_set_wakemon_params(pid_t pid, int rate_hz, int flags __unused)
633*2c2f96dcSApple OSS Distributions {
634*2c2f96dcSApple OSS Distributions struct proc_rlimit_control_wakeupmon params;
635*2c2f96dcSApple OSS Distributions
636*2c2f96dcSApple OSS Distributions params.wm_flags = WAKEMON_ENABLE;
637*2c2f96dcSApple OSS Distributions params.wm_rate = rate_hz;
638*2c2f96dcSApple OSS Distributions
639*2c2f96dcSApple OSS Distributions return proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, ¶ms);
640*2c2f96dcSApple OSS Distributions }
641*2c2f96dcSApple OSS Distributions
642*2c2f96dcSApple OSS Distributions #ifndef WAKEMON_GET_PARAMS
643*2c2f96dcSApple OSS Distributions #define WAKEMON_GET_PARAMS 0x4
644*2c2f96dcSApple OSS Distributions #define WAKEMON_SET_DEFAULTS 0x8
645*2c2f96dcSApple OSS Distributions #endif
646*2c2f96dcSApple OSS Distributions
647*2c2f96dcSApple OSS Distributions int
proc_get_wakemon_params(pid_t pid,int * rate_hz,int * flags)648*2c2f96dcSApple OSS Distributions proc_get_wakemon_params(pid_t pid, int *rate_hz, int *flags)
649*2c2f96dcSApple OSS Distributions {
650*2c2f96dcSApple OSS Distributions struct proc_rlimit_control_wakeupmon params;
651*2c2f96dcSApple OSS Distributions int error;
652*2c2f96dcSApple OSS Distributions
653*2c2f96dcSApple OSS Distributions params.wm_flags = WAKEMON_GET_PARAMS;
654*2c2f96dcSApple OSS Distributions
655*2c2f96dcSApple OSS Distributions if ((error = proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, ¶ms)) != 0) {
656*2c2f96dcSApple OSS Distributions return error;
657*2c2f96dcSApple OSS Distributions }
658*2c2f96dcSApple OSS Distributions
659*2c2f96dcSApple OSS Distributions *rate_hz = params.wm_rate;
660*2c2f96dcSApple OSS Distributions *flags = params.wm_flags;
661*2c2f96dcSApple OSS Distributions
662*2c2f96dcSApple OSS Distributions return 0;
663*2c2f96dcSApple OSS Distributions }
664*2c2f96dcSApple OSS Distributions
665*2c2f96dcSApple OSS Distributions int
proc_set_wakemon_defaults(pid_t pid)666*2c2f96dcSApple OSS Distributions proc_set_wakemon_defaults(pid_t pid)
667*2c2f96dcSApple OSS Distributions {
668*2c2f96dcSApple OSS Distributions struct proc_rlimit_control_wakeupmon params;
669*2c2f96dcSApple OSS Distributions
670*2c2f96dcSApple OSS Distributions params.wm_flags = WAKEMON_ENABLE | WAKEMON_SET_DEFAULTS;
671*2c2f96dcSApple OSS Distributions params.wm_rate = -1;
672*2c2f96dcSApple OSS Distributions
673*2c2f96dcSApple OSS Distributions return proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, ¶ms);
674*2c2f96dcSApple OSS Distributions }
675*2c2f96dcSApple OSS Distributions
676*2c2f96dcSApple OSS Distributions int
proc_disable_wakemon(pid_t pid)677*2c2f96dcSApple OSS Distributions proc_disable_wakemon(pid_t pid)
678*2c2f96dcSApple OSS Distributions {
679*2c2f96dcSApple OSS Distributions struct proc_rlimit_control_wakeupmon params;
680*2c2f96dcSApple OSS Distributions
681*2c2f96dcSApple OSS Distributions params.wm_flags = WAKEMON_DISABLE;
682*2c2f96dcSApple OSS Distributions params.wm_rate = -1;
683*2c2f96dcSApple OSS Distributions
684*2c2f96dcSApple OSS Distributions return proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, ¶ms);
685*2c2f96dcSApple OSS Distributions }
686*2c2f96dcSApple OSS Distributions
687*2c2f96dcSApple OSS Distributions int
proc_list_uptrs(int pid,uint64_t * buf,uint32_t bufsz)688*2c2f96dcSApple OSS Distributions proc_list_uptrs(int pid, uint64_t *buf, uint32_t bufsz)
689*2c2f96dcSApple OSS Distributions {
690*2c2f96dcSApple OSS Distributions return __proc_info(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDLISTUPTRS, 0,
691*2c2f96dcSApple OSS Distributions buf, bufsz);
692*2c2f96dcSApple OSS Distributions }
693*2c2f96dcSApple OSS Distributions
694*2c2f96dcSApple OSS Distributions int
proc_list_dynkqueueids(int pid,kqueue_id_t * buf,uint32_t bufsz)695*2c2f96dcSApple OSS Distributions proc_list_dynkqueueids(int pid, kqueue_id_t *buf, uint32_t bufsz)
696*2c2f96dcSApple OSS Distributions {
697*2c2f96dcSApple OSS Distributions return __proc_info(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDLISTDYNKQUEUES, 0,
698*2c2f96dcSApple OSS Distributions buf, bufsz);
699*2c2f96dcSApple OSS Distributions }
700*2c2f96dcSApple OSS Distributions
701*2c2f96dcSApple OSS Distributions
702*2c2f96dcSApple OSS Distributions int
proc_setcpu_percentage(pid_t pid,int action,int percentage)703*2c2f96dcSApple OSS Distributions proc_setcpu_percentage(pid_t pid, int action, int percentage)
704*2c2f96dcSApple OSS Distributions {
705*2c2f96dcSApple OSS Distributions proc_policy_cpuusage_attr_t attr;
706*2c2f96dcSApple OSS Distributions
707*2c2f96dcSApple OSS Distributions bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
708*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr = action;
709*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_percentage = percentage;
710*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, (uint64_t)0) != -1) {
711*2c2f96dcSApple OSS Distributions return 0;
712*2c2f96dcSApple OSS Distributions } else {
713*2c2f96dcSApple OSS Distributions return errno;
714*2c2f96dcSApple OSS Distributions }
715*2c2f96dcSApple OSS Distributions }
716*2c2f96dcSApple OSS Distributions
717*2c2f96dcSApple OSS Distributions int
proc_reset_footprint_interval(pid_t pid)718*2c2f96dcSApple OSS Distributions proc_reset_footprint_interval(pid_t pid)
719*2c2f96dcSApple OSS Distributions {
720*2c2f96dcSApple OSS Distributions return proc_rlimit_control(pid, RLIMIT_FOOTPRINT_INTERVAL, (void *)(uintptr_t)FOOTPRINT_INTERVAL_RESET);
721*2c2f96dcSApple OSS Distributions }
722*2c2f96dcSApple OSS Distributions
723*2c2f96dcSApple OSS Distributions int
proc_clear_cpulimits(pid_t pid)724*2c2f96dcSApple OSS Distributions proc_clear_cpulimits(pid_t pid)
725*2c2f96dcSApple OSS Distributions {
726*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, NULL, pid, (uint64_t)0) != -1) {
727*2c2f96dcSApple OSS Distributions return 0;
728*2c2f96dcSApple OSS Distributions } else {
729*2c2f96dcSApple OSS Distributions return errno;
730*2c2f96dcSApple OSS Distributions }
731*2c2f96dcSApple OSS Distributions }
732*2c2f96dcSApple OSS Distributions
733*2c2f96dcSApple OSS Distributions #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
734*2c2f96dcSApple OSS Distributions
735*2c2f96dcSApple OSS Distributions int
proc_setcpu_deadline(pid_t pid,int action,uint64_t deadline)736*2c2f96dcSApple OSS Distributions proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline)
737*2c2f96dcSApple OSS Distributions {
738*2c2f96dcSApple OSS Distributions proc_policy_cpuusage_attr_t attr;
739*2c2f96dcSApple OSS Distributions
740*2c2f96dcSApple OSS Distributions bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
741*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr = action;
742*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_deadline = deadline;
743*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, (uint64_t)0) != -1) {
744*2c2f96dcSApple OSS Distributions return 0;
745*2c2f96dcSApple OSS Distributions } else {
746*2c2f96dcSApple OSS Distributions return errno;
747*2c2f96dcSApple OSS Distributions }
748*2c2f96dcSApple OSS Distributions }
749*2c2f96dcSApple OSS Distributions
750*2c2f96dcSApple OSS Distributions int
proc_setcpu_percentage_withdeadline(pid_t pid,int action,int percentage,uint64_t deadline)751*2c2f96dcSApple OSS Distributions proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline)
752*2c2f96dcSApple OSS Distributions {
753*2c2f96dcSApple OSS Distributions proc_policy_cpuusage_attr_t attr;
754*2c2f96dcSApple OSS Distributions
755*2c2f96dcSApple OSS Distributions bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
756*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr = action;
757*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_percentage = percentage;
758*2c2f96dcSApple OSS Distributions attr.ppattr_cpu_attr_deadline = deadline;
759*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, (uint64_t)0) != -1) {
760*2c2f96dcSApple OSS Distributions return 0;
761*2c2f96dcSApple OSS Distributions } else {
762*2c2f96dcSApple OSS Distributions return errno;
763*2c2f96dcSApple OSS Distributions }
764*2c2f96dcSApple OSS Distributions }
765*2c2f96dcSApple OSS Distributions
766*2c2f96dcSApple OSS Distributions int
proc_appstate(int pid,int * appstatep)767*2c2f96dcSApple OSS Distributions proc_appstate(int pid, int * appstatep)
768*2c2f96dcSApple OSS Distributions {
769*2c2f96dcSApple OSS Distributions int state;
770*2c2f96dcSApple OSS Distributions
771*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_GET, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (proc_policy_attribute_t*)&state, pid, (uint64_t)0) != -1) {
772*2c2f96dcSApple OSS Distributions if (appstatep != NULL) {
773*2c2f96dcSApple OSS Distributions *appstatep = state;
774*2c2f96dcSApple OSS Distributions }
775*2c2f96dcSApple OSS Distributions return 0;
776*2c2f96dcSApple OSS Distributions } else {
777*2c2f96dcSApple OSS Distributions return errno;
778*2c2f96dcSApple OSS Distributions }
779*2c2f96dcSApple OSS Distributions }
780*2c2f96dcSApple OSS Distributions
781*2c2f96dcSApple OSS Distributions int
proc_setappstate(int pid,int appstate)782*2c2f96dcSApple OSS Distributions proc_setappstate(int pid, int appstate)
783*2c2f96dcSApple OSS Distributions {
784*2c2f96dcSApple OSS Distributions int state = appstate;
785*2c2f96dcSApple OSS Distributions
786*2c2f96dcSApple OSS Distributions switch (state) {
787*2c2f96dcSApple OSS Distributions case PROC_APPSTATE_NONE:
788*2c2f96dcSApple OSS Distributions case PROC_APPSTATE_ACTIVE:
789*2c2f96dcSApple OSS Distributions case PROC_APPSTATE_INACTIVE:
790*2c2f96dcSApple OSS Distributions case PROC_APPSTATE_BACKGROUND:
791*2c2f96dcSApple OSS Distributions case PROC_APPSTATE_NONUI:
792*2c2f96dcSApple OSS Distributions break;
793*2c2f96dcSApple OSS Distributions default:
794*2c2f96dcSApple OSS Distributions return EINVAL;
795*2c2f96dcSApple OSS Distributions }
796*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (proc_policy_attribute_t*)&state, pid, (uint64_t)0) != -1) {
797*2c2f96dcSApple OSS Distributions return 0;
798*2c2f96dcSApple OSS Distributions } else {
799*2c2f96dcSApple OSS Distributions return errno;
800*2c2f96dcSApple OSS Distributions }
801*2c2f96dcSApple OSS Distributions }
802*2c2f96dcSApple OSS Distributions
803*2c2f96dcSApple OSS Distributions int
proc_devstatusnotify(int devicestatus)804*2c2f96dcSApple OSS Distributions proc_devstatusnotify(int devicestatus)
805*2c2f96dcSApple OSS Distributions {
806*2c2f96dcSApple OSS Distributions int state = devicestatus;
807*2c2f96dcSApple OSS Distributions
808*2c2f96dcSApple OSS Distributions switch (devicestatus) {
809*2c2f96dcSApple OSS Distributions case PROC_DEVSTATUS_SHORTTERM:
810*2c2f96dcSApple OSS Distributions case PROC_DEVSTATUS_LONGTERM:
811*2c2f96dcSApple OSS Distributions break;
812*2c2f96dcSApple OSS Distributions default:
813*2c2f96dcSApple OSS Distributions return EINVAL;
814*2c2f96dcSApple OSS Distributions }
815*2c2f96dcSApple OSS Distributions
816*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_DEVSTATUS, (proc_policy_attribute_t*)&state, getpid(), (uint64_t)0) != -1) {
817*2c2f96dcSApple OSS Distributions return 0;
818*2c2f96dcSApple OSS Distributions } else {
819*2c2f96dcSApple OSS Distributions return errno;
820*2c2f96dcSApple OSS Distributions }
821*2c2f96dcSApple OSS Distributions }
822*2c2f96dcSApple OSS Distributions
823*2c2f96dcSApple OSS Distributions int
proc_pidbind(int pid,uint64_t threadid,int bind)824*2c2f96dcSApple OSS Distributions proc_pidbind(int pid, uint64_t threadid, int bind)
825*2c2f96dcSApple OSS Distributions {
826*2c2f96dcSApple OSS Distributions int state = bind;
827*2c2f96dcSApple OSS Distributions pid_t passpid = pid;
828*2c2f96dcSApple OSS Distributions
829*2c2f96dcSApple OSS Distributions switch (bind) {
830*2c2f96dcSApple OSS Distributions case PROC_PIDBIND_CLEAR:
831*2c2f96dcSApple OSS Distributions passpid = getpid(); /* ignore pid on clear */
832*2c2f96dcSApple OSS Distributions break;
833*2c2f96dcSApple OSS Distributions case PROC_PIDBIND_SET:
834*2c2f96dcSApple OSS Distributions break;
835*2c2f96dcSApple OSS Distributions default:
836*2c2f96dcSApple OSS Distributions return EINVAL;
837*2c2f96dcSApple OSS Distributions }
838*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_PIDBIND, (proc_policy_attribute_t*)&state, passpid, threadid) != -1) {
839*2c2f96dcSApple OSS Distributions return 0;
840*2c2f96dcSApple OSS Distributions } else {
841*2c2f96dcSApple OSS Distributions return errno;
842*2c2f96dcSApple OSS Distributions }
843*2c2f96dcSApple OSS Distributions }
844*2c2f96dcSApple OSS Distributions
845*2c2f96dcSApple OSS Distributions int
proc_can_use_foreground_hw(int pid,uint32_t * reason)846*2c2f96dcSApple OSS Distributions proc_can_use_foreground_hw(int pid, uint32_t *reason)
847*2c2f96dcSApple OSS Distributions {
848*2c2f96dcSApple OSS Distributions return __proc_info(PROC_INFO_CALL_CANUSEFGHW, pid, 0, 0, reason, sizeof(*reason));
849*2c2f96dcSApple OSS Distributions }
850*2c2f96dcSApple OSS Distributions #endif /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
851*2c2f96dcSApple OSS Distributions
852*2c2f96dcSApple OSS Distributions
853*2c2f96dcSApple OSS Distributions /* Donate importance to adaptive processes from this process */
854*2c2f96dcSApple OSS Distributions int
proc_donate_importance_boost(void)855*2c2f96dcSApple OSS Distributions proc_donate_importance_boost(void)
856*2c2f96dcSApple OSS Distributions {
857*2c2f96dcSApple OSS Distributions int rval;
858*2c2f96dcSApple OSS Distributions
859*2c2f96dcSApple OSS Distributions #if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
860*2c2f96dcSApple OSS Distributions rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
861*2c2f96dcSApple OSS Distributions PROC_POLICY_ACTION_ENABLE,
862*2c2f96dcSApple OSS Distributions PROC_POLICY_APPTYPE,
863*2c2f96dcSApple OSS Distributions PROC_POLICY_IOS_DONATEIMP,
864*2c2f96dcSApple OSS Distributions NULL, getpid(), (uint64_t)0);
865*2c2f96dcSApple OSS Distributions #else /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
866*2c2f96dcSApple OSS Distributions rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
867*2c2f96dcSApple OSS Distributions PROC_POLICY_ACTION_SET,
868*2c2f96dcSApple OSS Distributions PROC_POLICY_BOOST,
869*2c2f96dcSApple OSS Distributions PROC_POLICY_IMP_DONATION,
870*2c2f96dcSApple OSS Distributions NULL, getpid(), 0);
871*2c2f96dcSApple OSS Distributions #endif /* (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
872*2c2f96dcSApple OSS Distributions
873*2c2f96dcSApple OSS Distributions if (rval == 0) {
874*2c2f96dcSApple OSS Distributions return 0;
875*2c2f96dcSApple OSS Distributions } else {
876*2c2f96dcSApple OSS Distributions return errno;
877*2c2f96dcSApple OSS Distributions }
878*2c2f96dcSApple OSS Distributions }
879*2c2f96dcSApple OSS Distributions
880*2c2f96dcSApple OSS Distributions static __attribute__((noinline)) void
proc_importance_bad_assertion(char * reason)881*2c2f96dcSApple OSS Distributions proc_importance_bad_assertion(char *reason)
882*2c2f96dcSApple OSS Distributions {
883*2c2f96dcSApple OSS Distributions (void)reason;
884*2c2f96dcSApple OSS Distributions }
885*2c2f96dcSApple OSS Distributions
886*2c2f96dcSApple OSS Distributions /*
887*2c2f96dcSApple OSS Distributions * Use the address of these variables as the token. This way, they can be
888*2c2f96dcSApple OSS Distributions * printed in the debugger as useful names.
889*2c2f96dcSApple OSS Distributions */
890*2c2f96dcSApple OSS Distributions uint64_t important_boost_assertion_token = 0xfafafafafafafafa;
891*2c2f96dcSApple OSS Distributions uint64_t normal_boost_assertion_token = 0xfbfbfbfbfbfbfbfb;
892*2c2f96dcSApple OSS Distributions uint64_t non_boost_assertion_token = 0xfcfcfcfcfcfcfcfc;
893*2c2f96dcSApple OSS Distributions uint64_t denap_boost_assertion_token = 0xfdfdfdfdfdfdfdfd;
894*2c2f96dcSApple OSS Distributions
895*2c2f96dcSApple OSS Distributions /*
896*2c2f96dcSApple OSS Distributions * Accept the boost on a message, or request another boost assertion
897*2c2f96dcSApple OSS Distributions * if we have already accepted the implicit boost for this message.
898*2c2f96dcSApple OSS Distributions *
899*2c2f96dcSApple OSS Distributions * Returns EOVERFLOW if an attempt is made to take an extra assertion when not boosted.
900*2c2f96dcSApple OSS Distributions *
901*2c2f96dcSApple OSS Distributions * Returns EIO if the message was not a boosting message.
902*2c2f96dcSApple OSS Distributions * TODO: Return a 'non-boost' token instead.
903*2c2f96dcSApple OSS Distributions */
904*2c2f96dcSApple OSS Distributions int
proc_importance_assertion_begin_with_msg(mach_msg_header_t * msg,__unused mach_msg_trailer_t * trailer,uint64_t * assertion_token)905*2c2f96dcSApple OSS Distributions proc_importance_assertion_begin_with_msg(mach_msg_header_t *msg,
906*2c2f96dcSApple OSS Distributions __unused mach_msg_trailer_t *trailer,
907*2c2f96dcSApple OSS Distributions uint64_t *assertion_token)
908*2c2f96dcSApple OSS Distributions {
909*2c2f96dcSApple OSS Distributions int rval = 0;
910*2c2f96dcSApple OSS Distributions
911*2c2f96dcSApple OSS Distributions if (assertion_token == NULL) {
912*2c2f96dcSApple OSS Distributions return EINVAL;
913*2c2f96dcSApple OSS Distributions }
914*2c2f96dcSApple OSS Distributions
915*2c2f96dcSApple OSS Distributions #define LEGACYBOOSTMASK (MACH_MSGH_BITS_VOUCHER_MASK | MACH_MSGH_BITS_RAISEIMP)
916*2c2f96dcSApple OSS Distributions #define LEGACYBOOSTED(m) (((m)->msgh_bits & LEGACYBOOSTMASK) == MACH_MSGH_BITS_RAISEIMP)
917*2c2f96dcSApple OSS Distributions
918*2c2f96dcSApple OSS Distributions /* Is this a legacy boosted message? */
919*2c2f96dcSApple OSS Distributions if (LEGACYBOOSTED(msg)) {
920*2c2f96dcSApple OSS Distributions /*
921*2c2f96dcSApple OSS Distributions * Have we accepted the implicit boost for this message yet?
922*2c2f96dcSApple OSS Distributions * If we haven't accepted it yet, no need to call into kernel.
923*2c2f96dcSApple OSS Distributions */
924*2c2f96dcSApple OSS Distributions if ((msg->msgh_bits & MACH_MSGH_BITS_IMPHOLDASRT) == 0) {
925*2c2f96dcSApple OSS Distributions msg->msgh_bits |= MACH_MSGH_BITS_IMPHOLDASRT;
926*2c2f96dcSApple OSS Distributions *assertion_token = (uint64_t) &important_boost_assertion_token;
927*2c2f96dcSApple OSS Distributions return 0;
928*2c2f96dcSApple OSS Distributions }
929*2c2f96dcSApple OSS Distributions
930*2c2f96dcSApple OSS Distributions /* Request an additional boost count */
931*2c2f96dcSApple OSS Distributions rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
932*2c2f96dcSApple OSS Distributions PROC_POLICY_ACTION_HOLD,
933*2c2f96dcSApple OSS Distributions PROC_POLICY_BOOST,
934*2c2f96dcSApple OSS Distributions PROC_POLICY_IMP_IMPORTANT,
935*2c2f96dcSApple OSS Distributions NULL, getpid(), 0);
936*2c2f96dcSApple OSS Distributions if (rval == 0) {
937*2c2f96dcSApple OSS Distributions *assertion_token = (uint64_t) &important_boost_assertion_token;
938*2c2f96dcSApple OSS Distributions return 0;
939*2c2f96dcSApple OSS Distributions } else if (errno == EOVERFLOW) {
940*2c2f96dcSApple OSS Distributions proc_importance_bad_assertion("Attempted to take assertion while not boosted");
941*2c2f96dcSApple OSS Distributions return errno;
942*2c2f96dcSApple OSS Distributions } else {
943*2c2f96dcSApple OSS Distributions return errno;
944*2c2f96dcSApple OSS Distributions }
945*2c2f96dcSApple OSS Distributions }
946*2c2f96dcSApple OSS Distributions
947*2c2f96dcSApple OSS Distributions return EIO;
948*2c2f96dcSApple OSS Distributions }
949*2c2f96dcSApple OSS Distributions
950*2c2f96dcSApple OSS Distributions
951*2c2f96dcSApple OSS Distributions /*
952*2c2f96dcSApple OSS Distributions * Drop a boost assertion.
953*2c2f96dcSApple OSS Distributions * Returns EOVERFLOW on boost assertion underflow.
954*2c2f96dcSApple OSS Distributions */
955*2c2f96dcSApple OSS Distributions int
proc_importance_assertion_complete(uint64_t assertion_token)956*2c2f96dcSApple OSS Distributions proc_importance_assertion_complete(uint64_t assertion_token)
957*2c2f96dcSApple OSS Distributions {
958*2c2f96dcSApple OSS Distributions int rval = 0;
959*2c2f96dcSApple OSS Distributions
960*2c2f96dcSApple OSS Distributions if (assertion_token == 0) {
961*2c2f96dcSApple OSS Distributions return 0;
962*2c2f96dcSApple OSS Distributions }
963*2c2f96dcSApple OSS Distributions
964*2c2f96dcSApple OSS Distributions if (assertion_token == (uint64_t) &important_boost_assertion_token) {
965*2c2f96dcSApple OSS Distributions rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
966*2c2f96dcSApple OSS Distributions PROC_POLICY_ACTION_DROP,
967*2c2f96dcSApple OSS Distributions PROC_POLICY_BOOST,
968*2c2f96dcSApple OSS Distributions PROC_POLICY_IMP_IMPORTANT,
969*2c2f96dcSApple OSS Distributions NULL, getpid(), 0);
970*2c2f96dcSApple OSS Distributions if (rval == 0) {
971*2c2f96dcSApple OSS Distributions return 0;
972*2c2f96dcSApple OSS Distributions } else if (errno == EOVERFLOW) {
973*2c2f96dcSApple OSS Distributions proc_importance_bad_assertion("Attempted to drop too many assertions");
974*2c2f96dcSApple OSS Distributions return errno;
975*2c2f96dcSApple OSS Distributions } else {
976*2c2f96dcSApple OSS Distributions return errno;
977*2c2f96dcSApple OSS Distributions }
978*2c2f96dcSApple OSS Distributions } else {
979*2c2f96dcSApple OSS Distributions proc_importance_bad_assertion("Attempted to drop assertion with invalid token");
980*2c2f96dcSApple OSS Distributions return EIO;
981*2c2f96dcSApple OSS Distributions }
982*2c2f96dcSApple OSS Distributions }
983*2c2f96dcSApple OSS Distributions
984*2c2f96dcSApple OSS Distributions /*
985*2c2f96dcSApple OSS Distributions * Accept the De-Nap boost on a message, or request another boost assertion
986*2c2f96dcSApple OSS Distributions * if we have already accepted the implicit boost for this message.
987*2c2f96dcSApple OSS Distributions *
988*2c2f96dcSApple OSS Distributions * Interface is deprecated before it really got started - just as synonym
989*2c2f96dcSApple OSS Distributions * for proc_importance_assertion_begin_with_msg() now.
990*2c2f96dcSApple OSS Distributions */
991*2c2f96dcSApple OSS Distributions int
proc_denap_assertion_begin_with_msg(mach_msg_header_t * msg,uint64_t * assertion_token)992*2c2f96dcSApple OSS Distributions proc_denap_assertion_begin_with_msg(mach_msg_header_t *msg,
993*2c2f96dcSApple OSS Distributions uint64_t *assertion_token)
994*2c2f96dcSApple OSS Distributions {
995*2c2f96dcSApple OSS Distributions #pragma clang diagnostic push
996*2c2f96dcSApple OSS Distributions #pragma clang diagnostic ignored "-Wdeprecated-declarations"
997*2c2f96dcSApple OSS Distributions return proc_importance_assertion_begin_with_msg(msg, NULL, assertion_token);
998*2c2f96dcSApple OSS Distributions #pragma clang diagnostic pop
999*2c2f96dcSApple OSS Distributions }
1000*2c2f96dcSApple OSS Distributions
1001*2c2f96dcSApple OSS Distributions
1002*2c2f96dcSApple OSS Distributions /*
1003*2c2f96dcSApple OSS Distributions * Drop a denap boost assertion.
1004*2c2f96dcSApple OSS Distributions *
1005*2c2f96dcSApple OSS Distributions * Interface is deprecated before it really got started - just a synonym
1006*2c2f96dcSApple OSS Distributions * for proc_importance_assertion_complete() now.
1007*2c2f96dcSApple OSS Distributions */
1008*2c2f96dcSApple OSS Distributions int
proc_denap_assertion_complete(uint64_t assertion_token)1009*2c2f96dcSApple OSS Distributions proc_denap_assertion_complete(uint64_t assertion_token)
1010*2c2f96dcSApple OSS Distributions {
1011*2c2f96dcSApple OSS Distributions return proc_importance_assertion_complete(assertion_token);
1012*2c2f96dcSApple OSS Distributions }
1013*2c2f96dcSApple OSS Distributions
1014*2c2f96dcSApple OSS Distributions #if !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
1015*2c2f96dcSApple OSS Distributions
1016*2c2f96dcSApple OSS Distributions int
proc_clear_vmpressure(pid_t pid)1017*2c2f96dcSApple OSS Distributions proc_clear_vmpressure(pid_t pid)
1018*2c2f96dcSApple OSS Distributions {
1019*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_STARVATION, PROC_POLICY_RS_VIRTUALMEM, NULL, pid, (uint64_t)0) != -1) {
1020*2c2f96dcSApple OSS Distributions return 0;
1021*2c2f96dcSApple OSS Distributions } else {
1022*2c2f96dcSApple OSS Distributions return errno;
1023*2c2f96dcSApple OSS Distributions }
1024*2c2f96dcSApple OSS Distributions }
1025*2c2f96dcSApple OSS Distributions
1026*2c2f96dcSApple OSS Distributions /* set the current process as one who can resume suspended processes due to low virtual memory. Need to be root */
1027*2c2f96dcSApple OSS Distributions int
proc_set_owner_vmpressure(void)1028*2c2f96dcSApple OSS Distributions proc_set_owner_vmpressure(void)
1029*2c2f96dcSApple OSS Distributions {
1030*2c2f96dcSApple OSS Distributions int retval;
1031*2c2f96dcSApple OSS Distributions
1032*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_VMRSRCOWNER, (uint64_t)0, NULL, 0)) == -1) {
1033*2c2f96dcSApple OSS Distributions return errno;
1034*2c2f96dcSApple OSS Distributions }
1035*2c2f96dcSApple OSS Distributions
1036*2c2f96dcSApple OSS Distributions return 0;
1037*2c2f96dcSApple OSS Distributions }
1038*2c2f96dcSApple OSS Distributions
1039*2c2f96dcSApple OSS Distributions /* mark yourself to delay idle sleep on disk IO */
1040*2c2f96dcSApple OSS Distributions int
proc_set_delayidlesleep(void)1041*2c2f96dcSApple OSS Distributions proc_set_delayidlesleep(void)
1042*2c2f96dcSApple OSS Distributions {
1043*2c2f96dcSApple OSS Distributions int retval;
1044*2c2f96dcSApple OSS Distributions
1045*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)1, NULL, 0)) == -1) {
1046*2c2f96dcSApple OSS Distributions return errno;
1047*2c2f96dcSApple OSS Distributions }
1048*2c2f96dcSApple OSS Distributions
1049*2c2f96dcSApple OSS Distributions return 0;
1050*2c2f96dcSApple OSS Distributions }
1051*2c2f96dcSApple OSS Distributions
1052*2c2f96dcSApple OSS Distributions /* Reset yourself to delay idle sleep on disk IO, if already set */
1053*2c2f96dcSApple OSS Distributions int
proc_clear_delayidlesleep(void)1054*2c2f96dcSApple OSS Distributions proc_clear_delayidlesleep(void)
1055*2c2f96dcSApple OSS Distributions {
1056*2c2f96dcSApple OSS Distributions int retval;
1057*2c2f96dcSApple OSS Distributions
1058*2c2f96dcSApple OSS Distributions if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)0, NULL, 0)) == -1) {
1059*2c2f96dcSApple OSS Distributions return errno;
1060*2c2f96dcSApple OSS Distributions }
1061*2c2f96dcSApple OSS Distributions
1062*2c2f96dcSApple OSS Distributions return 0;
1063*2c2f96dcSApple OSS Distributions }
1064*2c2f96dcSApple OSS Distributions
1065*2c2f96dcSApple OSS Distributions /* disable the launch time backgroudn policy and restore the process to default group */
1066*2c2f96dcSApple OSS Distributions int
proc_disable_apptype(pid_t pid,int apptype)1067*2c2f96dcSApple OSS Distributions proc_disable_apptype(pid_t pid, int apptype)
1068*2c2f96dcSApple OSS Distributions {
1069*2c2f96dcSApple OSS Distributions switch (apptype) {
1070*2c2f96dcSApple OSS Distributions case PROC_POLICY_OSX_APPTYPE_TAL:
1071*2c2f96dcSApple OSS Distributions case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
1072*2c2f96dcSApple OSS Distributions break;
1073*2c2f96dcSApple OSS Distributions default:
1074*2c2f96dcSApple OSS Distributions return EINVAL;
1075*2c2f96dcSApple OSS Distributions }
1076*2c2f96dcSApple OSS Distributions
1077*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_DISABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1) {
1078*2c2f96dcSApple OSS Distributions return 0;
1079*2c2f96dcSApple OSS Distributions } else {
1080*2c2f96dcSApple OSS Distributions return errno;
1081*2c2f96dcSApple OSS Distributions }
1082*2c2f96dcSApple OSS Distributions }
1083*2c2f96dcSApple OSS Distributions
1084*2c2f96dcSApple OSS Distributions /* re-enable the launch time background policy if it had been disabled. */
1085*2c2f96dcSApple OSS Distributions int
proc_enable_apptype(pid_t pid,int apptype)1086*2c2f96dcSApple OSS Distributions proc_enable_apptype(pid_t pid, int apptype)
1087*2c2f96dcSApple OSS Distributions {
1088*2c2f96dcSApple OSS Distributions switch (apptype) {
1089*2c2f96dcSApple OSS Distributions case PROC_POLICY_OSX_APPTYPE_TAL:
1090*2c2f96dcSApple OSS Distributions case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
1091*2c2f96dcSApple OSS Distributions break;
1092*2c2f96dcSApple OSS Distributions default:
1093*2c2f96dcSApple OSS Distributions return EINVAL;
1094*2c2f96dcSApple OSS Distributions }
1095*2c2f96dcSApple OSS Distributions
1096*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_ENABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1) {
1097*2c2f96dcSApple OSS Distributions return 0;
1098*2c2f96dcSApple OSS Distributions } else {
1099*2c2f96dcSApple OSS Distributions return errno;
1100*2c2f96dcSApple OSS Distributions }
1101*2c2f96dcSApple OSS Distributions }
1102*2c2f96dcSApple OSS Distributions
1103*2c2f96dcSApple OSS Distributions #if !TARGET_OS_SIMULATOR
1104*2c2f96dcSApple OSS Distributions
1105*2c2f96dcSApple OSS Distributions int
proc_suppress(__unused pid_t pid,__unused uint64_t * generation)1106*2c2f96dcSApple OSS Distributions proc_suppress(__unused pid_t pid, __unused uint64_t *generation)
1107*2c2f96dcSApple OSS Distributions {
1108*2c2f96dcSApple OSS Distributions return 0;
1109*2c2f96dcSApple OSS Distributions }
1110*2c2f96dcSApple OSS Distributions
1111*2c2f96dcSApple OSS Distributions #endif /* !TARGET_OS_SIMULATOR */
1112*2c2f96dcSApple OSS Distributions
1113*2c2f96dcSApple OSS Distributions #endif /* !(TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR) */
1114*2c2f96dcSApple OSS Distributions
1115*2c2f96dcSApple OSS Distributions int
proc_set_no_smt(void)1116*2c2f96dcSApple OSS Distributions proc_set_no_smt(void)
1117*2c2f96dcSApple OSS Distributions {
1118*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_NO_SMT, 0, NULL, getpid(), (uint64_t)0) == -1) {
1119*2c2f96dcSApple OSS Distributions return errno;
1120*2c2f96dcSApple OSS Distributions }
1121*2c2f96dcSApple OSS Distributions return 0;
1122*2c2f96dcSApple OSS Distributions }
1123*2c2f96dcSApple OSS Distributions
1124*2c2f96dcSApple OSS Distributions int
proc_setthread_no_smt(void)1125*2c2f96dcSApple OSS Distributions proc_setthread_no_smt(void)
1126*2c2f96dcSApple OSS Distributions {
1127*2c2f96dcSApple OSS Distributions extern uint64_t __thread_selfid(void);
1128*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_THREAD, PROC_POLICY_ACTION_APPLY, PROC_POLICY_NO_SMT, 0, NULL, 0, __thread_selfid()) == -1) {
1129*2c2f96dcSApple OSS Distributions return errno;
1130*2c2f96dcSApple OSS Distributions }
1131*2c2f96dcSApple OSS Distributions return 0;
1132*2c2f96dcSApple OSS Distributions }
1133*2c2f96dcSApple OSS Distributions
1134*2c2f96dcSApple OSS Distributions int
proc_set_csm(uint32_t flags)1135*2c2f96dcSApple OSS Distributions proc_set_csm(uint32_t flags)
1136*2c2f96dcSApple OSS Distributions {
1137*2c2f96dcSApple OSS Distributions const uint32_t mask = PROC_CSM_ALL | PROC_CSM_TECS | PROC_CSM_NOSMT;
1138*2c2f96dcSApple OSS Distributions if ((flags & ~mask) != 0) {
1139*2c2f96dcSApple OSS Distributions return EINVAL;
1140*2c2f96dcSApple OSS Distributions }
1141*2c2f96dcSApple OSS Distributions
1142*2c2f96dcSApple OSS Distributions if (flags & (PROC_CSM_NOSMT | PROC_CSM_ALL)) {
1143*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_NO_SMT, 0, NULL, getpid(), (uint64_t)0) == -1) {
1144*2c2f96dcSApple OSS Distributions return errno;
1145*2c2f96dcSApple OSS Distributions }
1146*2c2f96dcSApple OSS Distributions }
1147*2c2f96dcSApple OSS Distributions
1148*2c2f96dcSApple OSS Distributions if (flags & (PROC_CSM_TECS | PROC_CSM_ALL)) {
1149*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_TECS, 0, NULL, getpid(), (uint64_t)0) == -1) {
1150*2c2f96dcSApple OSS Distributions return errno;
1151*2c2f96dcSApple OSS Distributions }
1152*2c2f96dcSApple OSS Distributions }
1153*2c2f96dcSApple OSS Distributions
1154*2c2f96dcSApple OSS Distributions return 0;
1155*2c2f96dcSApple OSS Distributions }
1156*2c2f96dcSApple OSS Distributions
1157*2c2f96dcSApple OSS Distributions int
proc_setthread_csm(uint32_t flags)1158*2c2f96dcSApple OSS Distributions proc_setthread_csm(uint32_t flags)
1159*2c2f96dcSApple OSS Distributions {
1160*2c2f96dcSApple OSS Distributions extern uint64_t __thread_selfid(void);
1161*2c2f96dcSApple OSS Distributions const uint32_t mask = PROC_CSM_ALL | PROC_CSM_TECS | PROC_CSM_NOSMT;
1162*2c2f96dcSApple OSS Distributions if ((flags & ~mask) != 0) {
1163*2c2f96dcSApple OSS Distributions return EINVAL;
1164*2c2f96dcSApple OSS Distributions }
1165*2c2f96dcSApple OSS Distributions
1166*2c2f96dcSApple OSS Distributions if (flags & (PROC_CSM_NOSMT | PROC_CSM_ALL)) {
1167*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_THREAD, PROC_POLICY_ACTION_APPLY, PROC_POLICY_NO_SMT, 0, NULL, 0, __thread_selfid()) == -1) {
1168*2c2f96dcSApple OSS Distributions return errno;
1169*2c2f96dcSApple OSS Distributions }
1170*2c2f96dcSApple OSS Distributions }
1171*2c2f96dcSApple OSS Distributions
1172*2c2f96dcSApple OSS Distributions if (flags & (PROC_CSM_TECS | PROC_CSM_ALL)) {
1173*2c2f96dcSApple OSS Distributions if (__process_policy(PROC_POLICY_SCOPE_THREAD, PROC_POLICY_ACTION_APPLY, PROC_POLICY_TECS, 0, NULL, 0, __thread_selfid()) == -1) {
1174*2c2f96dcSApple OSS Distributions return errno;
1175*2c2f96dcSApple OSS Distributions }
1176*2c2f96dcSApple OSS Distributions }
1177*2c2f96dcSApple OSS Distributions
1178*2c2f96dcSApple OSS Distributions return 0;
1179*2c2f96dcSApple OSS Distributions }
1180