Spec couche 0 — Famille process, affinité CPU (sched_setaffinity)
Spécification technique — Version 1.0 (cible kernel : Linux 6.12 LTS). Extension
de la famille process.
Position
Ce document spécifie le primitif d’affinité CPU de la couche 0 — épingler une
tâche sur un sous-ensemble de CPU logiques. Manque identifié en spécifiant la
couche 1 : air-thread::cpu_affinity en a besoin et aucun wrapper
sched_setaffinity/sched_getaffinity n’existait.
Placement : famille process. L’affinité est une propriété d’ordonnancement
d’une tâche (identifiée par un Tid) ; elle vit donc avec gettid,
clone3, waitid, setpgid… dans air-sys-syscall::process. Le masque
réutilise CpuSet (déjà défini dans air-sys-types::system au Temps 3a pour
IORING_REGISTER_IOWQ_AFF) — type partagé, non recréé. (Alternative écartée :
famille system — mais system couvre l’information machine (uname, sysinfo,
entropie), pas l’ordonnancement d’une tâche précise.)
Émergence (méthode doc-d’abord). Comme inotify, ce manque a été révélé par la spécification de la couche 1 — consommer la couche 0 fait apparaître ses trous. Pas de spec préalable : ce document est produit avant l’implémentation.
Surface
#![allow(unused)]
fn main() {
/// `sched_setaffinity(2)` — fixe l'affinité CPU d'une tâche : elle ne sera
/// ordonnancée que sur les CPU présents dans `cpus`. `tid = None` = tâche
/// appelante (sentinelle kernel `0` typée en `Option`, ADR-021 conv. 1).
pub fn set_cpu_affinity(tid: Option<Tid>, cpus: &CpuSet) -> Result<(), Errno>;
/// `sched_getaffinity(2)` — lit l'affinité courante **dans** `cpus` (buffer
/// fourni par l'appelant, zéro allocation). `tid = None` = tâche appelante.
pub fn get_cpu_affinity(tid: Option<Tid>, cpus: &mut CpuSet) -> Result<(), Errno>;
}
CpuSetréutilisé (air-sys-types::system,CPU_SETSIZE = 1024bits / 128 octets, layoutcpu_set_t) :new/set/clear/contains/count/is_empty/as_bytes.get_cpu_affinityécrit dans le masque via un pointeur sur le&mut CpuSet(#[repr(C)]sans padding ⇒ tout motif d’octets valide) — aucun nouvel accesseur ajouté au type.None= tâche appelante : traduit enpid = 0(jamais exposé comme entier magique — ADR-021 conv. 1).- EINTR :
sched_*affinityne sont pas interruptibles ; aucun retry caché (ADR-021 conv. 2 reste la règle générale).
Syscalls sous-jacents (vérifiés uapi 6.12, par arche)
| Syscall | x86_64 | aarch64 |
|---|---|---|
sched_setaffinity | 203 | 122 |
sched_getaffinity | 204 | 123 |
set : le kernel lit len octets du masque (asm readonly). get : le
kernel écrit dans le masque (asm sans readonly) et retourne le nombre
d’octets remplis (≥ 0) ou -errno. La taille passée est size_of::<CpuSet>()
(128 octets) ≥ la taille kernel de cpumask — le kernel remplit ce qu’il a et
laisse le reste à zéro.
Préconditions / erreurs
set_cpu_affinity:- [
Errno::EINVAL] :cpusne contient aucun CPU autorisé / en ligne. - [
Errno::ESRCH] : aucune tâche ne porte cetid. - [
Errno::EPERM] : privilèges insuffisants (changer l’affinité d’une tâche d’un autre utilisateur, ou contrainte cpuset cgroup).
- [
get_cpu_affinity:- [
Errno::ESRCH] :tidinexistant. - [
Errno::EINVAL] : taille de masque incohérente — ne se produit pas avec unCpuSetdeCPU_SETSIZEbits (toujours ≥ la taille kernel).
- [
Tests
- Round-trip (réel) :
getl’affinité courante (count ≥ 1),setà un sous-ensemble (CPU 0, toujours en ligne),getet vérifiercontains(0)+count == 1, puis restaurer l’affinité d’origine. NonevsSome(tid): les deux ciblent la tâche appelante (Some(gettid())).- Erreurs : masque vide →
EINVAL;tidinexistant →ESRCH. - Cross-arch : numéros vérifiés x86_64 + aarch64 ; tests exécutés sur les deux.
- Couverture 100 % lignes + branches (les chemins
Ok/Errréels couvrent les deux bras ;affinity_pidNone/Somecouverts) ; aucune exception attendue.
Décisions de fond
- Affinité dans
process(ordonnancement d’une tâche), masque partagé depuissystem::CpuSet— pas de duplication de type. None= tâche appelante (pid = 0typé), conforme ADR-021 conv. 1.- Buffer fourni, zéro allocation pour
get(l’appelant possède leCpuSet). - Primitif débloquant la couche 1 (
air-thread::cpu_affinity).
Licence du document : MPL 2.0
Statut : Spécification technique de l’affinité CPU (sched_set/getaffinity),
extension de la famille process (couche 0), cible kernel 6.12 LTS.