Skip to content

CPU Pinning on macOS

Apple operating systems explicitly do not support CPU pinning in a shipping configuration.

This is unlike almost every other shipping OS, so do not even try to check if the feature is present there to rely on it for shipping applications. Use QoS features instead on Apple platforms. (or anywhere else for that matter)

How it’s gated

#if DEVELOPMENT || DEBUG

#include <pexpert/pexpert.h>
extern int32_t sysctl_get_bound_cpuid(void);
extern kern_return_t sysctl_thread_bind_cpuid(int32_t cpuid);
static int
sysctl_kern_sched_thread_bind_cpu SYSCTL_HANDLER_ARGS
{
#pragma unused(oidp, arg1, arg2)

	/*
	 * DO NOT remove this bootarg guard or make this non-development.
	 * This kind of binding should only be used for tests and
	 * experiments in a custom configuration, never shipping code.
	 */

	if (!PE_parse_boot_argn("enable_skstb", NULL, 0)) {
		return ENOENT;
	}

(in bsd/kern/sys_generic.c)

Not only the CPU pinning code is gated behind a #ifdef to not work on production kernels, it is also gated behind a boot argument (enable_skstb).

Note that cluster pinning support is also gated behind the same mechanism, for systems shipping with multiple clusters.

How to use CPU pinning for development purposes then?

To do that, you need to follow the instructions on how to set up a development kernel. You can pick one from the Kernel Debug Kit available at the Apple developer website, which also contains the instructions necessary to install a custom kernel on Intel-based Macs.

After doing so, set the enable_skstb=1 boot argument then reboot. The corresponding sysctl()s will then become available.

Leave a Reply

Your email address will not be published.