2 * Copyright (c) 2013 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
29 #include <sys/resource.h>
31 #include <sys/errno.h>
34 #include <mach/mach.h>
35 #include <mach/task_policy.h>
37 #define QOS_PARAMETER_LATENCY 0
38 #define QOS_PARAMETER_THROUGHPUT 1
40 static void usage(void);
41 static int parse_disk_policy(const char *strpolicy
);
42 static int parse_qos_tier(const char *strpolicy
, int parameter
);
44 int main(int argc
, char * argv
[])
47 bool flagx
= false, flagX
= false, flagb
= false;
48 int flagd
= -1, flagg
= -1;
49 struct task_qos_policy qosinfo
= { LATENCY_QOS_TIER_UNSPECIFIED
, THROUGHPUT_QOS_TIER_UNSPECIFIED
};
51 while ((ch
= getopt(argc
, argv
, "xXbd:g:t:l:")) != -1) {
63 flagd
= parse_disk_policy(optarg
);
65 warnx("Could not parse '%s' as a disk policy", optarg
);
70 flagg
= parse_disk_policy(optarg
);
72 warnx("Could not parse '%s' as a disk policy", optarg
);
77 qosinfo
.task_throughput_qos_tier
= parse_qos_tier(optarg
, QOS_PARAMETER_THROUGHPUT
);
78 if (qosinfo
.task_throughput_qos_tier
== -1) {
79 warnx("Could not parse '%s' as a qos tier", optarg
);
84 qosinfo
.task_latency_qos_tier
= parse_qos_tier(optarg
, QOS_PARAMETER_LATENCY
);
85 if (qosinfo
.task_latency_qos_tier
== -1) {
86 warnx("Could not parse '%s' as a qos tier", optarg
);
103 warnx("Incompatible options -x, -X");
108 ret
= setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY
, IOPOL_SCOPE_PROCESS
, IOPOL_VFS_HFS_CASE_SENSITIVITY_FORCE_CASE_SENSITIVE
);
110 err(EX_SOFTWARE
, "setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY...)");
115 ret
= setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY
, IOPOL_SCOPE_PROCESS
, IOPOL_VFS_HFS_CASE_SENSITIVITY_DEFAULT
);
117 err(EX_SOFTWARE
, "setiopolicy_np(IOPOL_TYPE_VFS_HFS_CASE_SENSITIVITY...)");
122 ret
= setpriority(PRIO_DARWIN_PROCESS
, 0, PRIO_DARWIN_BG
);
124 err(EX_SOFTWARE
, "setpriority()");
129 ret
= setiopolicy_np(IOPOL_TYPE_DISK
, IOPOL_SCOPE_PROCESS
, flagd
);
131 err(EX_SOFTWARE
, "setiopolicy_np(...IOPOL_SCOPE_PROCESS...)");
136 ret
= setiopolicy_np(IOPOL_TYPE_DISK
, IOPOL_SCOPE_DARWIN_BG
, flagg
);
138 err(EX_SOFTWARE
, "setiopolicy_np(...IOPOL_SCOPE_DARWIN_BG...)");
142 if (qosinfo
.task_latency_qos_tier
!= LATENCY_QOS_TIER_UNSPECIFIED
||
143 qosinfo
.task_throughput_qos_tier
!= THROUGHPUT_QOS_TIER_UNSPECIFIED
){
144 ret
= task_policy_set(mach_task_self(), TASK_OVERRIDE_QOS_POLICY
, (task_policy_t
)&qosinfo
, TASK_QOS_POLICY_COUNT
);
145 if (ret
!= KERN_SUCCESS
){
146 err(EX_SOFTWARE
, "task_policy_set(...TASK_OVERRIDE_QOS_POLICY...)");
150 ret
= execvp(argv
[0], argv
);
152 err(EX_NOINPUT
, "Could not execute %s", argv
[0]);
158 static void usage(void)
160 fprintf(stderr
, "Usage: %s [-x|-X] [-d <policy>] [-g policy] [-b] [-t <tier>] [-l <tier>] <program> [<pargs> [...]]\n", getprogname());
164 static int parse_disk_policy(const char *strpolicy
)
169 /* first try as an integer */
170 policy
= strtol(strpolicy
, &endptr
, 0);
171 if (endptr
&& (endptr
[0] == '\0') && (strpolicy
[0] != '\0')) {
172 /* parsed complete string as a number */
176 if (0 == strcasecmp(strpolicy
, "DEFAULT") ) {
177 return IOPOL_DEFAULT
;
178 } else if (0 == strcasecmp(strpolicy
, "IMPORTANT")) {
179 return IOPOL_IMPORTANT
;
180 } else if (0 == strcasecmp(strpolicy
, "PASSIVE")) {
181 return IOPOL_PASSIVE
;
182 } else if (0 == strcasecmp(strpolicy
, "THROTTLE")) {
183 return IOPOL_THROTTLE
;
184 } else if (0 == strcasecmp(strpolicy
, "UTILITY")) {
185 return IOPOL_UTILITY
;
186 } else if (0 == strcasecmp(strpolicy
, "STANDARD")) {
187 return IOPOL_STANDARD
;
193 static int parse_qos_tier(const char *strtier
, int parameter
){
197 /* first try as an integer */
198 policy
= strtol(strtier
, &endptr
, 0);
199 if (endptr
&& (endptr
[0] == '\0') && (strtier
[0] != '\0')) {
202 return parameter
? THROUGHPUT_QOS_TIER_0
: LATENCY_QOS_TIER_0
;
205 return parameter
? THROUGHPUT_QOS_TIER_1
: LATENCY_QOS_TIER_1
;
208 return parameter
? THROUGHPUT_QOS_TIER_2
: LATENCY_QOS_TIER_2
;
211 return parameter
? THROUGHPUT_QOS_TIER_3
: LATENCY_QOS_TIER_3
;
214 return parameter
? THROUGHPUT_QOS_TIER_4
: LATENCY_QOS_TIER_4
;
217 return parameter
? THROUGHPUT_QOS_TIER_5
: LATENCY_QOS_TIER_5
;