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, ¤t_percentage, ¤t_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, ¶ms);
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, ¶ms)) != 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, ¶ms);
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, ¶ms);
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