|
NAMEDEFINE_IFUNC —
define a kernel function with an implementation selected at
run-time
SYNOPSIS#include <machine/ifunc.h>
DESCRIPTIONifuncs are a linker feature which allows the programmer to define functions whose implementation is selected at boot-time or module load-time. TheDEFINE_IFUNC macro can be used to define an ifunc. The
selection is performed by a resolver function, which returns a pointer to the
selected function. ifunc resolvers are invoked very early during the
machine-dependent initialization routine, or at load time for dynamically
loaded modules. Resolution must occur before the first call to an ifunc. ifunc
resolution is performed after CPU features are enumerated and after the
kernel's environment is initialized. The typical use-case for an ifunc is a
routine whose behavior depends on optional CPU features. For example, newer
generations of a given CPU architecture may provide an instruction to optimize
a common operation. To avoid the overhead of testing for the CPU feature each
time the operation is performed, an ifunc can be used to provide two
implementations for the operation: one targeting platforms with the extra
instruction, and one for older platforms.
Because The EXAMPLESifunc resolvers are executed early during boot, before most kernel facilities are available. They are effectively limited to checking CPU feature flags and tunables.static size_t fast_strlen(const char *s __unused) { size_t len; /* Fast, but may not be correct in all cases. */ __asm("movq $42,%0\n" : "=r" (len)); return (len); } static size_t slow_strlen(const char *s) { const char *t; for (t = s; *t != '\0'; t++); return (t - s); } DEFINE_IFUNC(, size_t, strlen, (const char *)) { int enabled; enabled = 1; TUNABLE_INT_FETCH("debug.use_fast_strlen", &enabled); if (enabled && (cpu_features & CPUID_FAST_STRLEN) != 0) return (fast_strlen); else return (slow_strlen); } This defines a SEE ALSOelf(5)NOTESifuncs are not supported on all architectures. They require both toolchain support, to emit function symbols of typeSTT_GNU_IFUNC , and kernel linker support to invoke
ifunc resolvers during boot or during module load.
Visit the GSP FreeBSD Man Page Interface. |