diff options
| author | Olivier Certner <olce@FreeBSD.org> | 2026-10-09 14:29:06 +0000 |
|---|---|---|
| committer | Olivier Certner <olce@FreeBSD.org> | 2026-11-03 17:42:22 +0000 |
| commit | 510331fa376309ae0860b91bd501c9c5a73e86a7 (patch) | |
| tree | 777a2c3a46b627432b47dd96206aced1d894cf37 /sys/arm64/include | |
| parent | 28c31242758323499eaf8af1f03fc4ae4a960205 (diff) | |
sched: Automatically namespace schedulers' implementation functions
This renames back scheduler implementation functions to their old names,
i.e., the same name as the interface functions, in the source code,
while providing the infrastructure to still produce from them C symbols
namespaced by the scheduler implementation, in order to avoid symbol
collisions with interface dispatching functions and other scheduler
implementations when multiple ones are compiled in. In a nutshell, the
implementation consists in re-routing interface names to implementation
names via the C preprocessor.
The main reasons for this change are that different implementation names:
1. Break navigating code with ctags-like tools like in-tree ctags,
Global and Universal Ctags.
2. Spoils inlining opportunities in internal scheduler code if not
careful. This alternatively could be regained by changing call
points to use scheduler-specific names, but that does not prevent
people from inadvertently adding more calls to interface functions.
Also, having to namespace calls with the implementation name in the
implementation itself can be seen as code clutter.
3. Introduces avoidable cognitive burden, for example in the form of
having to ask oneself whether internal scheduler functions should be
namespaced or not, and then when calling them which their actual
names are.
However, C symbol collisions create difficulties with debugging and ELF
manipulation tools, including when printing backtraces (which scheduler
implementation is in use?). For example, as of this writing,
'disassemble' in GDB will choose one of the existing functions and
disassemble it without mentioning the existing others; our ddb(4) will
set a breakpoint on one of these functions only (which should be
improved); etc. So keeping namespaced symbol names was desirable, which
is why symbol re-routing via the C preprocessor was chosen.
People wanting to extract information from ELF files will have to use
full symbol names instead of source code names. This is certainly
a drawback, but we expect that people will spend by far more time on the
code rather than trying to disassemble some particular implementation
function, so the inconvenience will barely occur in practice. Also,
DWARF information matching machine code to source code location stays
undisturbed and gdb will continue to display matching source code
correctly. ctags-like tool are likely to never implement macro
substitution when definitions are in other files, or if they do to never
enable it by default, as this would considerably slow down source
parsing (Universal Ctags reports a 2x slowdown just by enabling
expansions for definitions that are in the *same* file). LSPs have not
been tested; we however expect this change will cause nothing but minor
annoyances when using them. Writing new calls to scheduler functions
should work as usual in terms of help/completion (including in
implementations, as corresponding implementation and interface functions
have same signature). Even automatically producing implementation
function signatures when adding a new definition is expected to work.
Please report if not the case.
The implementation of the machinery to substitute interface names by
implementation names has two parts.
First, a new generated per-implementation-specific header has to be
included in each implementation ("sched_<NAME>_ns.h"). It contains
simple C preprocessor substitutions, such as, taking the example of ULE:
#define sched_clock sched_ule_clock
#define sched_switch sched_ule_switch
allowing to use the interface names in place of the implementation names
in the implementation itself. It also checks that an implementation
actually defined SCHED_IMPLEMENTATION and to the same value that was
used to produce it.
These headers are generated from the pattern header
'sys/kern/sched_ns.h' through directives in 'sys/conf/files', via the
C preprocessor using the already existing X macros and some light
post-processing by the new 'sys/tools/sched_impl_ns.awk' script.
Second, <sys/sched.h> declares all implementation functions when
included from an implementation, so that out-of-order references within
the implementation do not cause problems, as it was before multiple
schedulers could coexist.
Implementations must define SCHED_IMPLEMENTATION to their name used as
the namespacing symbol part (e.g., ule or 4bsd), which used to be the
name passed as the first argument to DECLARE_SCHEDULER(). This argument
is now redundant and has been removed. That same macro with same value
has to be defined in the directives from 'sys/conf/files' for each
implementation's namespacing header to be produced properly.
For added safety, <sys/sched.h> does not provide interface functions'
declarations when SCHED_IMPLEMENTATION is defined anymore, so that
implementations can never inadvertently call these functions.
Reviewed by: mchoo
MFC after: 3 days
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D60644
Diffstat (limited to 'sys/arm64/include')
0 files changed, 0 insertions, 0 deletions
