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