#include <mach/mach.h>
#include <mach/task.h>
-
-#include <sys/resource.h>
+#include <mach/thread_act.h>
+#include <mach/thread_policy.h>
#include <errno.h>
#include <getopt.h>
void usage(void);
-#ifndef PRIO_DARWIN_PROCESS
-#define PRIO_DARWIN_PROCESS 4 /* Second argument is a PID */
-#endif
void
usage(void)
{
- fprintf(stderr, "Usage: mean -t <pid>\n");
- fprintf(stderr, "\tthrottle <pid>'s usage of cpu, I/O, and networking\n");
- fprintf(stderr, "mean -u <pid>\n");
- fprintf(stderr, "\treturn <pid> to normal priority\n");
- fprintf(stderr, "mean -[s|r] <pid>\n");
- fprintf(stderr, "\tsuspend or resume <pid>\n");
+ fprintf(stderr, "Usage: mean -[r|s|u] <pid>\n");
+ fprintf(stderr, "\tLower <pid>'s priority.\n");
+ fprintf(stderr, "\t-u: return <pid> to normal priority\n");
+ fprintf(stderr, "\t-r: resume <pid>\n");
+ fprintf(stderr, "\t-s: suspend <pid>\n");
exit(0);
}
int
main(int argc, char **argv)
{
- int pid, err, ch;
+ int pid, err, i, ch;
+ unsigned int count;
mach_port_t task;
- int priority = 0;
+ thread_act_array_t threads;
+ thread_precedence_policy_data_t policy;
- boolean_t do_resume = 0, do_suspend = 0;
- boolean_t do_throttle = 0, do_undo = 0;
+ boolean_t do_high = 0, do_resume = 0, do_suspend = 0;
+ boolean_t do_low = 1;
if (argc < 2)
usage();
- while ((ch = getopt(argc, argv, "rstu")) != -1)
+ while ((ch = getopt(argc, argv, "rsu")) != -1)
switch (ch) {
case 'u':
- do_undo = 1;
+ do_high = 1;
+ do_low = 0;
continue;
case 'r':
do_resume = 1;
+ do_low = 0;
continue;
case 's':
do_suspend = 1;
- continue;
- case 't':
- do_throttle = 1;
+ do_low = 0;
continue;
default:
usage();
pid = atoi(*argv);
if (!pid)
usage();
+
+ err = task_for_pid(mach_task_self(), pid, &task);
+ if (err) {
+ fprintf(stderr, "Failed to get task port (%d)\n", err);
+ exit(0);
+ }
- if (do_throttle || do_undo) {
- priority = PRIO_DARWIN_BG;
-
- if (do_undo)
- priority = 0;
+ if (do_low || do_high) {
- err = setpriority(PRIO_DARWIN_PROCESS, pid, priority);
+ err = task_threads(task, &threads, &count);
if (err) {
- fprintf(stderr, "Failed to set priority (%d)\n", errno);
+ fprintf(stderr, "Failed to get thread list (%d)\n", err);
exit(0);
}
- }
- if (do_suspend || do_resume) {
- err = task_for_pid(mach_task_self(), pid, &task);
- if (err) {
- fprintf(stderr, "Failed to get task port (%d)\n", err);
- exit(0);
- }
+ if (do_low)
+ policy.importance = -100;
+ else
+ policy.importance = 0;
- if (do_suspend) {
- err = task_suspend(task);
+ for (i = 0; i < count; i++) {
+ err = thread_policy_set(threads[i],
+ THREAD_PRECEDENCE_POLICY,
+ (thread_policy_t) &policy,
+ THREAD_PRECEDENCE_POLICY_COUNT);
if (err) {
- fprintf(stderr, "Failed to suspend task (%d)\n", err);
+ fprintf(stderr, "Failed to set thread priority (%d)\n", err);
+ exit(0);
}
-
}
- if (do_resume) {
- err = task_resume(task);
- if (err) {
- fprintf(stderr, "Failed to resume task (%d)\n", err);
- }
+ printf("Process %d's threads set to %s priority.\n", pid,
+ (do_low ? "lowest" : "highest"));
+ }
+
+ if (do_suspend) {
+ err = task_suspend(task);
+ if (err) {
+ fprintf(stderr, "Failed to suspend task (%d)\n", err);
+ } else {
+ printf("Process %d suspended.\n", pid);
+ }
+
+ }
+
+ if (do_resume) {
+ err = task_resume(task);
+ if (err) {
+ fprintf(stderr, "Failed to resume task (%d)\n", err);
+ } else {
+ printf("Process %d resumed.\n", pid);
}
}