5 // Copyright (c) 2019 Apple Inc. All rights reserved.
17 #include <mach/mach.h>
21 printf("usage: cpuctl [ list ]\n");
22 printf(" cpuctl { offline | online } <cpu> [ <cpu>... ]\n");
26 static void fetch_cpu_info(host_t
*priv_port
,
27 processor_port_array_t proc_ports
,
28 mach_msg_type_number_t proc_count
,
29 processor_basic_info_data_t
*cpus
)
31 for (int i
= 0; i
< proc_count
; i
++) {
32 mach_msg_type_number_t info_count
= PROCESSOR_BASIC_INFO_COUNT
;
34 if (processor_info(proc_ports
[i
], PROCESSOR_BASIC_INFO
, priv_port
,
35 (processor_info_t
)&cpus
[i
], &info_count
) != KERN_SUCCESS
) {
36 errx(EX_OSERR
, "processor_info(%d) failed", i
);
41 static int do_cmd_list(mach_msg_type_number_t proc_count
, processor_basic_info_data_t
*cpus
)
44 for (int i
= 0; i
< proc_count
; i
++) {
45 int lowest_slot
= INT_MAX
;
47 for (int j
= 0; j
< proc_count
; j
++) {
48 int slot
= cpus
[j
].slot_num
;
49 if (slot
> prev_lowest
&& slot
< lowest_slot
) {
55 errx(EX_OSERR
, "slot numbers are out of range");
57 processor_basic_info_data_t
*cpu
= &cpus
[lowest_idx
];
58 printf("CPU%d: %-7s type=%x,%x master=%d\n",
60 cpu
->running
? "online" : "offline",
65 prev_lowest
= lowest_slot
;
70 static int find_cpu_by_slot(mach_msg_type_number_t proc_count
,
71 processor_basic_info_data_t
*cpus
,
74 for (int i
= 0; i
< proc_count
; i
++) {
75 if (cpus
[i
].slot_num
== slot
)
81 int main(int argc
, char **argv
)
85 while ((opt
= getopt(argc
, argv
, "h")) != -1) {
93 if (host_get_host_priv_port(mach_host_self(), &priv_port
) != KERN_SUCCESS
)
94 errx(EX_OSERR
, "host_get_host_priv_port() failed");
96 processor_port_array_t proc_ports
;
97 mach_msg_type_number_t proc_count
;
98 if (host_processors(priv_port
, &proc_ports
, &proc_count
) != KERN_SUCCESS
)
99 errx(EX_OSERR
, "host_processors() failed");
101 processor_basic_info_data_t
*cpus
= calloc(proc_count
, sizeof(*cpus
));
103 errx(EX_OSERR
, "calloc() failed");
104 fetch_cpu_info(&priv_port
, proc_ports
, proc_count
, cpus
);
107 return do_cmd_list(proc_count
, cpus
);
109 const char *cmd
= argv
[optind
];
112 if (!strcmp(cmd
, "list"))
113 return do_cmd_list(proc_count
, cpus
);
116 if (!strncmp(cmd
, "off", 3))
118 else if (strncmp(cmd
, "on", 2))
125 for (; optind
< argc
; optind
++) {
127 int slot
= (int)strtoul(argv
[optind
], &endp
, 0);
131 int cpu
= find_cpu_by_slot(proc_count
, cpus
, slot
);
133 errx(EX_USAGE
, "Invalid CPU ID %d", slot
);
136 if (processor_start(proc_ports
[cpu
]) != KERN_SUCCESS
)
137 errx(EX_OSERR
, "processor_start(%u) failed", cpu
);
139 if (processor_exit(proc_ports
[cpu
]) != KERN_SUCCESS
)
140 errx(EX_OSERR
, "processor_exit(%u) failed", cpu
);