Scheduling & CPU-Affinität (WP-8): Steuert auf welchen CPUs ein Prozess oder Thread läuft (CPU-Pinning), liest und setzt den Nice-Wert (Priorität) und gibt die CPU freiwillig ab. Enthält Helfer zum Aufbau von cpu_set_t-Bitmasken für bis zu 1024 CPUs.
→ Standard Library · std.process_ext · std.thread
| Konstante | Wert | Beschreibung |
|---|---|---|
CPU_SET_SIZE | 128 | Größe einer cpu_set_t-Bitmap in Bytes (1024 CPUs) |
| Konstante | Wert | Beschreibung |
|---|---|---|
PRIO_PROCESS | 0 | GetPriority/SetPriority operiert auf Prozess-ID |
PRIO_PGRP | 1 | Operiert auf Prozessgruppen-ID |
PRIO_USER | 2 | Operiert auf Benutzer-ID |
| Signatur | Beschreibung |
|---|---|
SchedYield(): int64 | Gibt die CPU freiwillig ab — der aktuelle Thread wird ans Ende der Run-Queue gestellt. Gibt immer 0 zurück |
| Signatur | Beschreibung |
|---|---|
SchedSetAffinity(pid: int64, cpuMask: int64): int64 | Setzt die CPU-Affinität von pid auf die in cpuMask (alloc(CPU_SET_SIZE)) erlaubten CPUs. pid=0 → aktueller Prozess. Gibt 0 bei Erfolg |
SchedGetAffinity(pid: int64, outMask: int64): int64 | Liest die aktuelle CPU-Affinität von pid in outMask (alloc(CPU_SET_SIZE)). Gibt 0 bei Erfolg |
| Signatur | Beschreibung |
|---|---|
CpuSetZero(buf: int64) | Setzt alle Bits auf 0 — keine CPU erlaubt |
CpuSetAdd(buf: int64, cpu: int64) | Erlaubt CPU cpu (0-basiert) in der Maske |
CpuSetRemove(buf: int64, cpu: int64) | Verbietet CPU cpu in der Maske |
CpuSetHas(buf: int64, cpu: int64): bool | Gibt true zurück wenn CPU cpu in der Maske gesetzt ist |
CpuSetCount(buf: int64): int64 | Zählt die Anzahl erlaubter CPUs in der Maske |
| Signatur | Beschreibung |
|---|---|
GetPriority(pid: int64): int64 | Gibt den Nice-Wert von pid zurück (−20 = höchste, 19 = niedrigste Priorität). pid=0 → aktueller Prozess |
SetPriority(pid: int64, nice: int64): int64 | Setzt den Nice-Wert von pid. Nicht-Root kann nur erhöhen (Priorität senken). Gibt 0 bei Erfolg |
| Signatur | Beschreibung |
|---|---|
GetCPU(cpuOut: int64, nodeOut: int64): int64 | Schreibt CPU-Nummer in cpuOut und NUMA-Knoten in nodeOut (je alloc(8)). nodeOut=0 auf Nicht-NUMA-Systemen |
GetCurrentCPU(): int64 | Gibt die aktuelle CPU-Nummer direkt zurück (< 0 bei Fehler) |
import std.sched;
import std.alloc;
fn PinToCore(cpu: int64): bool {
var mask: int64 := alloc(CPU_SET_SIZE);
CpuSetZero(mask);
CpuSetAdd(mask, cpu);
var r := SchedSetAffinity(0, mask);
free(mask, CPU_SET_SIZE);
return r == 0;
}
import std.sched;
import std.alloc;
import std.io;
fn PrintAffinity(): void {
var mask: int64 := alloc(CPU_SET_SIZE);
SchedGetAffinity(0, mask);
Print("Erlaubte CPUs: ");
var cpu: int64 := 0;
while (cpu < 64) { // Erste 64 CPUs prüfen
if (CpuSetHas(mask, cpu)) {
Print(IntToStr(cpu) + " ");
}
cpu := cpu + 1;
}
PrintLn("Anzahl: " + IntToStr(CpuSetCount(mask)));
free(mask, CPU_SET_SIZE);
}
import std.sched;
import std.alloc;
fn LimitToFirstFourCores(): void {
var mask: int64 := alloc(CPU_SET_SIZE);
CpuSetZero(mask);
CpuSetAdd(mask, 0);
CpuSetAdd(mask, 1);
CpuSetAdd(mask, 2);
CpuSetAdd(mask, 3);
SchedSetAffinity(0, mask);
free(mask, CPU_SET_SIZE);
}
import std.sched;
import std.io;
fn PrintSchedInfo(): void {
var cpu := GetCurrentCPU();
var nice := GetPriority(0);
PrintLn("Läuft auf CPU: " + IntToStr(cpu));
PrintLn("Nice-Wert: " + IntToStr(nice));
}
fn LowerPriority(): void {
// Priorität senken (Nice erhöhen) — kein Root nötig
SetPriority(0, 10);
}
import std.sched;
// Gibt CPU ab während auf ein Flag gewartet wird (statt busy-wait).
fn WaitForFlag(flagAddr: int64): void {
while (peek64(flagAddr) == 0) {
SchedYield();
}
}
SetPriority mit einem Nice-Wert < 0 (höhere Priorität) erfordert Root oder CAP_SYS_NICE.GetCurrentCPU ist nicht garantiert stabil: Der Scheduler kann den Prozess jederzeit auf eine andere CPU verschieben.SchedYield gibt immer 0 zurück und schlägt nie fehl.CpuSetCount iteriert alle 128 Bytes (1024 CPUs) — für normale Systeme ist das vernachlässigbar.std.process_ext — Credentials, Session, unamestd.thread — Threads (Affinität gilt pro Thread)std.process — fork, exec, waitpidLetzte Aktualisierung: 2026-06-05