CPUSET(9)

πŸ’– CPUSET(9) β€” cpuset manipulation macros πŸ’–

okay bestie, sit DOWN, because this one is a whole vibe. this is the cpuset(9) page from the Kernel Developer's Manual, and it's literally the group chat of CPU sets. every macro you could ever need to manage which CPUs are in your little bitmask clique. let's go πŸ¦‹


✨ NAME ✨

cpuset(9) β€” CPUSET_T_INITIALIZER, CPUSET_FSET, CPU_CLR, CPU_COPY, CPU_ISSET, CPU_SET, CPU_ZERO, CPU_FILL, CPU_SETOF, CPU_EMPTY, CPU_ISFULLSET, CPU_FFS, CPU_COUNT, CPU_SUBSET, CPU_OVERLAP, CPU_CMP, CPU_OR, CPU_AND, CPU_NAND, CPU_CLR_ATOMIC, CPU_SET_ATOMIC, CPU_SET_ATOMIC_ACQ, CPU_AND_ATOMIC, CPU_OR_ATOMIC, CPU_COPY_STORE_REL β€” cpuset manipulation macros


🌸 SYNOPSIS 🌸

#include <sys/_cpuset.h>
#include <sys/cpuset.h>

CPUSET_T_INITIALIZER(ARRAY_CONTENTS);

CPUSET_FSET

CPU_CLR(size_t cpu_idx, cpuset_t *cpuset);

CPU_COPY(cpuset_t *from, cpuset_t *to);

bool
CPU_ISSET(size_t cpu_idx, cpuset_t *cpuset);

CPU_SET(size_t cpu_idx, cpuset_t *cpuset);

CPU_ZERO(cpuset_t *cpuset);

CPU_FILL(cpuset_t *cpuset);

CPU_SETOF(size_t cpu_idx, cpuset_t *cpuset);

bool
CPU_EMPTY(cpuset_t *cpuset);

bool
CPU_ISFULLSET(cpuset_t *cpuset);

int
CPU_FFS(cpuset_t *cpuset);

int
CPU_COUNT(cpuset_t *cpuset);

bool
CPU_SUBSET(cpuset_t *haystack, cpuset_t *needle);

bool
CPU_OVERLAP(cpuset_t *cpuset1, cpuset_t *cpuset2);

bool
CPU_CMP(cpuset_t *cpuset1, cpuset_t *cpuset2);

CPU_OR(cpuset_t *dst, cpuset_t *src);

CPU_AND(cpuset_t *dst, cpuset_t *src);

CPU_NAND(cpuset_t *dst, cpuset_t *src);

CPU_CLR_ATOMIC(size_t cpu_idx, cpuset_t *cpuset);

CPU_SET_ATOMIC(size_t cpu_idx, cpuset_t *cpuset);

CPU_SET_ATOMIC_ACQ(size_t cpu_idx, cpuset_t *cpuset);

CPU_AND_ATOMIC(cpuset_t *dst, cpuset_t *src);

CPU_OR_ATOMIC(cpuset_t *dst, cpuset_t *src);

CPU_COPY_STORE_REL(cpuset_t *from, cpuset_t *to);

πŸŽ€ DESCRIPTION πŸŽ€

so the cpuset(9) macro family is your flexible, efficient CPU set implementation, and it's backed by the bitset(9) macros. the whole concept is so clean: each CPU gets exactly one bit. periodt.

  • the maximum number of CPUs representable by cpuset_t is MAXCPU.
  • individual CPUs inside cpusets are referenced with indices zero through MAXCPU - 1.

ngl, that's the entire mental model. slay.


  • CPUSET_T_INITIALIZER() β€” lets you initialize a cpuset_t with a compile time literal value. πŸ’…
  • CPUSET_FSET() β€” defines a compile time literal that CPUSET_T_INITIALIZER() can use, representing a full cpuset (all CPUs present). for examples of CPUSET_T_INITIALIZER() and CPUSET_FSET() in action, peek the β€œCPUSET_T_INITIALIZER EXAMPLE” section below πŸ‘‘
  • CPU_CLR() β€” removes CPU cpu_idx from the cpuset pointed to by cpuset. the CPU_CLR_ATOMIC() macro is literally identical, except the bit representing the CPU is cleared with atomic machine instructions. atomic girly behavior πŸ”₯
  • CPU_COPY() β€” copies the contents of the cpuset from to the cpuset to. CPU_COPY_STORE_REL() is similar, but it copies component machine words from from and writes them to to with atomic store with release semantics. (that is, if to is composed of multiple machine words, CPU_COPY_STORE_REL() performs multiple individually atomic operations.) no cap.
  • CPU_SET() β€” adds CPU cpu_idx to the cpuset pointed to by cpuset, if it's not already present. CPU_SET_ATOMIC() is identical, except the bit representing the CPU is set with atomic machine instructions. and CPU_SET_ATOMIC_ACQ() sets the bit representing the CPU with atomic acquire semantics. different flavor, same energy ✨
  • CPU_ZERO() β€” removes all CPUs from cpuset. empty. cleared. ghosted πŸ’€
  • CPU_FILL() β€” adds all CPUs to cpuset. the opposite of ghosting, it's giving main character energy πŸ‘‘
  • CPU_SETOF() β€” removes all CPUs in cpuset before adding only CPU cpu_idx. out with the old, in with the one πŸŽ€
  • CPU_EMPTY() β€” returns true if cpuset is empty.
  • CPU_ISFULLSET() β€” returns true if cpuset is full (aka the set of all CPUs).
  • CPU_FFS() β€” returns the 1-index of the first (lowest) CPU in cpuset, or zero if cpuset is empty. and listen, like with ffs(3), to use the non-zero result of CPU_FFS() as a cpu_idx index parameter to any other cpuset(9) macro, you must subtract one from the result. yes really. we'll scream about this again in CAVEATS 🫠
  • CPU_COUNT() β€” returns the total number of CPUs in cpuset. the headcount. the census. πŸ’…
  • CPU_SUBSET() β€” returns true if needle is a subset of haystack. needle in a haystack, get it? iconic.
  • CPU_OVERLAP() β€” returns true if cpuset1 and cpuset2 have any common CPUs. (that is, if cpuset1 AND cpuset2 is not the empty set.) they share a vibe check 🌈
  • CPU_CMP() β€” returns true if cpuset1 is NOT equal to cpuset2. read that again bestie, it's a not β€” this one is the inverse of what your brain wants it to be 😭
  • CPU_OR() β€” adds CPUs present in src to dst. (it is the cpuset(9) equivalent of the scalar: dst |= src.) CPU_OR_ATOMIC() is similar, but sets the bits representing CPUs in the component machine words in dst with atomic machine instructions. (that is, if dst is composed of multiple machine words, CPU_OR_ATOMIC() performs multiple individually atomic operations.)
  • CPU_AND() β€” removes CPUs absent from src from dst. (it is the cpuset(9) equivalent of the scalar: dst &= src.) CPU_AND_ATOMIC() is similar, with the same atomic semantics as CPU_OR_ATOMIC(). 🌸
  • CPU_NAND() β€” removes CPUs in src from dst. (it is the cpuset(9) equivalent of the scalar: dst &= ~ src.)

🧚 CPUSET_T_INITIALIZER EXAMPLE 🧚

okay here's the actual code, verbatim, no edits, because i would never:

cpuset_t myset;

/* Initialize myset to filled (all CPUs) */
myset = CPUSET_T_INITIALIZER(CPUSET_FSET);

/* Initialize myset to only the lowest CPU */
myset = CPUSET_T_INITIALIZER(0x1);

look at that. chef's kiss. CPUSET_FSET for everything, 0x1 for just the lowest CPU. beautiful πŸ’–


πŸ¦‹ SEE ALSO πŸ¦‹


πŸ“œ HISTORY πŸ“œ

<sys/cpuset.h> first appeared in FreeBSD 7.1, released in January 2009, and in FreeBSD 8.0, released in November 2009.

this manual page first appeared in FreeBSD 11.0.

a whole lineage. we love a legacy πŸ’œ


πŸ‘‘ AUTHORS πŸ‘‘

the cpuset(9) macros were written by Jeff Roberson <jeff@FreeBSD.org>.

this manual page was written by Conrad Meyer <cem@FreeBSD.org>.

thank you for your service, kings 🫢


πŸ’€ CAVEATS πŸ’€

unlike every other reference to individual set members, which are zero-indexed, CPU_FFS() returns a one-indexed result (or zero if the cpuset is empty).

not me warning you twice about this. i did say it in the DESCRIPTION. i meant it. subtract one. fr fr. πŸ™ˆ


okay that's the whole page, bestie, every single macro and caveat intact ✨ this was the Debian version of the page, dated July 29, 2016 β€” so yeah, a little vintage, but the bitset stays slaying πŸ’… mwah, go forth and set some CPUs πŸŽ€

πŸ“¦ where this page comes from