Jade VM-Scheduler & Intrinsic-Grenze¶
Status: Konsolidierter normativer Entwurf
Version: 0.3.0
Datum: 2026-09-23
Geltungsbereich: Tasks, Scheduling, Suspension, I/O-Wakeup, Timer, Engine-Runtime-Konfiguration, native Ausführung außerhalb der Worker und Scheduler-Intrinsics
Bezieht sich auf: Runtime-Modell (03), VM Instruction Set (05), Intrinsics & VM API (08), JadeValue/Register-Layout (11), IR (13), Effect Rows & Throw[E], Fehlermodell, FFI-Spec, JME-/Handle-Vertrag
Ring-Zugehörigkeit: Scheduler Ring 0; JDL-/Stdlib-Abstraktionen darüber Ring 1/2
Host: Zig; konkrete Zig-Strukturen sind nicht Teil des Vertrags
1. Architektur¶
Der Scheduler ist Teil der Jade VM. Er führt M leichtgewichtige Tasks auf N konfigurierbaren Worker-Threads aus.
Zwei Fragen bleiben getrennt:
Task wird wieder lauffähig:
Event oder Zeit
Lauffähige Task bekommt CPU:
Run Queue / Worker / Reduction-Budget
Event-/I/O-Poller Master Clock
│ │
▼ ▼
Event-Wakeup Engine Timer-Wheel
│ │
└─────────┬───────────┘
▼
Runnable
│
▼
Worker / Run Queue
│
▼
VM Loop
1.1 M:N und Work-Stealing¶
Work-Stealing ist die vorgesehene Mehrworker-Strategie. Eine Referenzreihenfolge für Worker ist:
- lokale Run Queue,
- globale Inject-/Wakeup-Queue,
- Work-Stealing,
- Worker parken.
Deque-Typ, Steal-Größe und Victim-Auswahl sind Implementierungsdetails. Die beobachtbare Semantik einer Jade-Task darf nicht davon abhängen, auf welchem Worker sie ausgeführt wird.
Native Ausführungsanforderungen ändern diese Regel nicht. Ein nativer Aufruf mit fester Affinität wird nicht an einen Worker gebunden, sondern außerhalb des Worker-Pools auf einer NativeExecutionLane ausgeführt (§1.3). Nach seiner Rückkehr darf die wartende Jade-Task auf einem beliebigen Worker fortgesetzt werden.
1.2 Event-Poller und Clock¶
Der Event-/I/O-Poller übersetzt externe Completions in Scheduler-Wakeups. Die konkrete OS-Anbindung (epoll, io_uring, kqueue, IOCP oder äquivalent) ist Plattformdetail.
Die Master Clock bedient ausschließlich aktive Timer-Wheels. Der Scheduler besitzt keinen globalen Heartbeat. Ohne Arbeit, Events oder aktive Timer darf die Runtime schlafen.
1.3 Native Ausführung außerhalb der Worker¶
Worker-Threads führen Jade-Tasks aus. Native Aufrufe dürfen davon getrennte Host-Threads verwenden, wenn ihr materialisierter Vertrag das verlangt. Dafür gibt es zwei mechanische Formen:
NativeExecutionLane
genau ein Host-Thread
führt native Aufrufe nacheinander aus
kann mehrere AffinityDomains bedienen
NativeBlockingPool
kleiner Vorrat an Host-Threads
führt blockierende native Aufrufe ohne feste Affinität aus
Threads beider Formen sind keine Worker. Auf ihnen läuft keine Jade-Task und kein VM-Loop für Benutzercode.
Ein fertiger nativer Aufruf wird wie jede andere externe Completion in einen Scheduler-Wakeup übersetzt.
Jade-Tasks
│
Worker-Pool (M:N)
│ │
native direct│ │ Task wartet
│ ├──────── NativeBlockingPool
│ └──────── NativeExecutionLane
│ │
│ Completion
│ ▼
└──────────────────── Wakeup
Was ein nativer Aufruf verlangt, entscheidet nicht der Scheduler. Er liest es aus dem materialisierten FFI-Vertrag (§3.7). Die Wahrheit über Handles, ihre AffinityDomain und ihren Exklusiv-Zustand, gehört der JME.
2. Task-Modell¶
Eine Task ist die kleinste vom Scheduler verwaltete, suspendierbare VM-Ausführungseinheit.
Konzeptionell:
Task
id
schedulingState
executionState // IP, Frames, Register
reductions
engineId
waitCondition?
nativeEntryToken?
cancellationRequested
outcome?
nativeEntryToken ist die mechanische Identität eines laufenden nativen Eintrittspfads (§3.11). Er ist kein JDL-Wert und keine Autorität. Eine Task trägt ihn gegebenenfalls; er gehört nicht ihr.
2.1 Schedulerzustand und Ausgang¶
Schedulerzustand:
Task-Ausgang:
Beides sind getrennte Dimensionen. Completed bedeutet nicht automatisch Erfolg.
stateDiagram-v2
[*] --> Runnable: spawn
Runnable --> Running: dispatch
Running --> Runnable: preemption / yield
Running --> Waiting: event / timer
Waiting --> Runnable: wakeup / cancellation
Running --> Completed: return / throw / trap / cancellation
Completed --> [*]
2.2 Task-Grenze und Throw[E]¶
Ein Throw[E] darf nicht durch den Stack einer anderen Task unwinden.
Eine Join-/Wait-Abstraktion darf den Fehler im wartenden Task wieder lokal als Throw[E] erzeugen. Die konkrete JDL-Task-API wird separat spezifiziert.
Throw[E], Trap und Cancellation bleiben getrennt.
2.3 Task vs. Actor¶
Tasks besitzen keine eingebaute Mailbox und keine Supervision.
Actors, Channels und Mailboxes dürfen generische Wait-/Wakeup-Mechanismen verwenden, gehören aber nicht zum Scheduler-Core.
3. Scheduling und Suspension¶
3.1 Reduction-basierte Fairness¶
Jede laufende Task besitzt ein Reduction-Budget aus ihrer EngineRuntimeConfig.
Bei erschöpftem Budget wird die Task an einem VM-sicheren Preemption-Point gespeichert und erneut als Runnable eingereiht.
Das ist keine willkürliche OS-Präemption in nativen Code. Eine dauerhaft runnable Task darf andere runnable Tasks nicht dauerhaft verdrängen.
3.2 Event-getriebene Suspension¶
Muss eine Operation warten, registriert die Runtime eine Wait-Condition und setzt die aktuelle Task auf Waiting.
Der Scheduler kennt nur die Wait-/Wakeup-Identität, nicht die fachliche Bedeutung des Events.
3.3 Suspension ist kein Result¶
VM-interner Ausführungskontrollfluss muss mindestens unterscheiden können zwischen:
Die konkrete Struktur ist Implementierungsdetail.
Die frühere Form JadeResult.yield() ist kein JDL-Result[T,E] und wird nicht als Fehlersemantik verwendet.
3.4 Transparente Suspension in JDL¶
JDL besitzt keine spezielle async-Funktionsklasse und benötigt für normale Service-Aufrufe keine async/await-Schlüsselwörter.
def loadConfig(path: Path) ->{Fs, Throw[IoError]} Config {
val data = Fs.read(path)
parseConfig(data)
}
Fs.read darf die aktuelle Task suspendieren. Die Funktion bleibt eine normale JDL-Funktion.
Effect Row:
semantische Anforderungen und propagierbare Effekte
Scheduler:
wann die Berechnung weiterlaufen kann
Suspendierbarkeit ist kein Row-Element; es gibt keinen Async-Effekt.
3.5 Explizite Parallelität¶
Suspension erzeugt keine neue Task. Parallele Arbeit wird explizit durch Task-Erzeugung gestartet, konzeptionell über spawn.
// exemplarisch; Oberfläche separat zu spezifizieren
val first = spawn { load("a") }
val b = load("b")
val a = first.join()
Task-Captures unterliegen den normalen Ownership-/Sharing-Regeln der Task-Grenze.
3.6 Cancellation¶
Cancellation ist kooperativer Scheduler-Kontrollfluss und kein Throw[E].
- die Anforderung bleibt sticky,
- wartende Tasks werden geweckt,
- laufende Tasks beobachten sie an definierten Checkpoints,
- es gibt keine willkürliche Unterbrechung beliebigen VM-/FFI-Codes.
Der Fault-Pfad wartet nicht auf Cancellation. Trappt eine Task, erklärt die Runtime ihre FaultDomain sofort für nicht mehr ausführbar und gibt ihre Ressourcen getrennt davon frei, sobald keine Holds mehr offen sind (jade-fehlermodell §7, §8). Cancellation bleibt davon unberührt kooperativ.
Eine höhere Abstraktion darf Cancellation in einen Wert oder Domain-Fehler übersetzen.
Wartet eine Task auf einen nativen Aufruf oder auf die Freigabe eines exklusiven Handles, gilt dasselbe wie für jedes andere Warten: Sie wird geweckt und verlässt die Warteschlange. Was mit einem bereits laufenden nativen Aufruf geschieht, regelt §3.12.
3.7 Nativer Dispatch¶
Der FFI-Vertrag eines nativen Aufrufs trägt zwei voneinander unabhängige Angaben:
Der Scheduler setzt daraus um:
| affinity | execution | Ausführungsort | Jade-Task |
|---|---|---|---|
any |
direct |
aktueller Worker, synchron | läuft weiter |
any |
blocking |
NativeBlockingPool |
wartet |
stable |
direct |
gebundene NativeExecutionLane |
wartet |
stable |
blocking |
gebundene NativeExecutionLane |
wartet |
blocking heißt: Dieser Aufruf darf seinen Host-Thread länger blockieren und darf deshalb keinen Worker blockieren. Es heißt nicht „immer der Pool“. Bei stable ist der zulässige Host-Thread die Lane; blocking überstimmt stable nie.
any plus direct läuft auf dem Worker, ohne dass das Reduction-Budget während des nativen Aufrufs zählt. Die Angabe direct ist eine Zusage des Bindings, dass der Aufruf kurz ist. Stimmt sie nicht, leidet die Fairness des Workers, nicht die Semantik.
3.8 NativeExecutionLane und AffinityDomain¶
Eine AffinityDomain bezeichnet eine Menge nativer Ressourcen, deren affine Aufrufe auf demselben Host-Thread ausgeführt werden müssen.
Jede aktive AffinityDomain ist genau einer NativeExecutionLane zugeordnet. Eine Lane:
- besitzt genau einen Host-Thread,
- führt native Aufrufe nacheinander aus,
- darf mehrere AffinityDomains bedienen,
- führt keine Jade-Tasks aus.
Für die gesamte Lebensdauer einer AffinityDomain bleibt ihr Host-Thread derselbe. Welche Lane eine neue Domain bekommt, ist Implementierungsdetail.
Eine Domain entsteht, wenn ein nativer Aufruf laut FFI-Vertrag ein Handle mit fester Affinität erzeugt. Der Scheduler wählt dann zuerst die Lane und führt den erzeugenden Aufruf dort aus; erst danach entsteht das Handle und wird von der JME an die Domain gebunden. Handles, die aus einem gebundenen Handle hervorgehen, erben dessen Domain. Die Form dieser Angaben steht in der FFI-Spec.
3.9 Stabile Domains sind bereits serialisiert¶
Eine Lane führt Aufrufe nacheinander aus. Ein Handle mit affinity = stable kann deshalb nie von zwei nativen Aufrufen gleichzeitig benutzt werden. Eine zusätzliche Exklusiv-Sperre ist dafür nicht nötig.
Davon getrennt bleibt der Wiedereintritt während eines noch laufenden Aufrufs über einen Callback (§3.11).
3.10 Exklusive nicht-affine Handles¶
Für Handles mit affinity = any und access = exclusive:
Handle frei → der eintretende Token erhält den Eintritt
Handle durch anderen NativeEntryToken belegt → aufrufende Task wartet
Handle durch denselben Token belegt → Trap
Im dritten Fall würde der Eintritt auf sich selbst warten. Das ist ein Programmierfehler ohne sinnvolle Reaktion und damit nach dem Fehlermodell ein Trap.
Welcher Token ein Handle gerade benutzt, weiß die JME. Der Scheduler besitzt nur das Warten und Wecken. Wird das Handle frei, wird mindestens eine wartende Task wieder runnable.
3.11 NativeEntryToken und Wiedereintritt¶
Ein NativeEntryToken entsteht beim Eintritt in einen nativen Aufrufpfad.
Ruft nativer Code synchron nach Jade zurück, trägt die Callback-Task denselben Token. Erzeugt diese Task strukturierte Kind-Tasks und wartet auf sie, erben diese den Token für die Dauer dieses strukturierten Pfads.
Ein synchroner Callback mit Token T darf keine native Ausführung in eine AffinityDomain anfordern, die derselbe Token T gerade aktiv hält. Ein solcher Eintritt trappt: Die Lane wartet auf den Callback und könnte den neuen Auftrag erst nach dessen Rückkehr ausführen.
Grenze. Der Token ist kein allgemeiner Deadlock-Detektor. Ein Wartekreis über lose Kommunikation bleibt unerkannt:
Callback wartet auf eine Kanal-Nachricht
andere Task wartet auf das exklusive Handle
Handle wird erst nach Rückkehr des Callbacks frei
Einen solchen Kreis zu erkennen, bräuchte einen allgemeinen Wartegraphen (Suchwort: wait-for graph). v0.3 verspricht das nicht. Es ist ein Programmierfehler. Introspection darf den Wartegraphen zur Diagnose sichtbar machen.
3.12 Cancellation während nativer Ausführung¶
Cancellation einer wartenden Task beendet einen bereits laufenden nativen Aufruf nicht.
- Die Task darf ihren gewöhnlichen Cancellation-Pfad fortsetzen.
- Der native Aufruf läuft weiter und behält alle Holds, die er für seine sichere Ausführung braucht.
- Nach seiner Rückkehr wird das Ergebnis nur zugestellt, wenn noch ein Empfänger existiert.
- Die Holds werden erst gelöst, wenn der native Eintritt tatsächlich beendet ist.
Bietet eine native API eine eigene Abbruchoperation, kann eine höhere FFI-Abstraktion einen Abbruchpfad beschreiben. Der Scheduler erfindet ihn nicht.
3.13 Native Callback-Eintritte¶
Ein nativer Callback führt nie Jade-Code direkt auf dem aufrufenden nativen Thread aus. Er wird in eine Jade-Task übersetzt und über den gewöhnlichen Scheduler ausgeführt. Das gilt für Lanes, für den Pool und für fremde Threads, die eine Bibliothek selbst erzeugt. Kein fremder Thread wird dadurch zum Worker.
asynchron Callback-Task wird eingereiht; der native Thread wartet nicht
synchron Callback-Task wird eingereiht; der native Thread wartet auf ihren Ausgang
und setzt danach den nativen Aufruf fort; der Token wird weitergegeben
Die Callback-Task läuft unter der Engine-Konfiguration des Eintritts, der sie ausgelöst hat: bei synchronen Callbacks die der ursprünglichen Task, bei asynchronen die, die bei der Registrierung des Callbacks festgehalten wurde.
Offen: Endet eine synchrone Callback-Task nicht mit Success (sondern mit Failure, Cancelled oder Trap), braucht der wartende native Thread trotzdem einen Rückgabewert für C. Welcher das ist, muss der Callback-Vertrag in der FFI-Spec festlegen. Ein Trap in der Callback-Task folgt davon unabhängig dem Fehlermodell.
3.14 Blockierende Aufrufe auf stabilen Lanes¶
Blockiert ein Aufruf auf einer Lane, können bis zu seiner Rückkehr keine weiteren Aufrufe dieser Lane laufen. Das verletzt keine Semantik, es verlängert nur die Wartezeit anderer Domains derselben Lane.
Eine Implementierung darf Domains, deren Vertrag blockierende Aufrufe enthält, bevorzugt auf eigene oder wenig geteilte Lanes legen. Das ist Scheduling-Policy, keine Semantikzusage.
4. Engine-Konfiguration und Zeit¶
4.1 Trennung der Ebenen¶
Der Scheduler kennt keine semantische JDL-Engine. Er konsumiert ausschließlich EngineRuntimeConfig.
Tasks speichern ihre engineId.
4.2 EngineRuntimeConfig¶
Scheduler-relevante Konfiguration umfasst mindestens:
Capabilities gehören nicht zur Scheduler-Semantik. Enforcement erfolgt an RuntimeBus-/VM-Grenzen.
Registrierung und Änderungen der Runtime-Konfiguration laufen über den RuntimeBus.
4.3 Engine-lokale Timer-Wheels¶
Nicht jede Engine besitzt ein Timer-Wheel.
typisch zeitgetrieben:
Rendering, periodische Jobs, Health Checks, Simulation
typisch eventgetrieben:
HTTP-Transport, Socket-Completion, viele Actor-/Channel-Wakeups
Ein hierarchisches Timer-Wheel ist die vorgesehene Referenzimplementierung. Anzahl der Ebenen und Slots sind kein Sprachvertrag.
4.4 Overrun-Policies¶
Für periodische Arbeit existieren drei Policies:
Drift nächster Lauf relativ zum tatsächlichen Abschluss; kein Aufstauen
Skip verpasste Intervalle überspringen
Queue verpasste Intervalle nachholen
Drift ist Default, sofern die Engine nichts anderes verlangt.
4.5 Beobachtbarkeit¶
Scheduler und Timer-Wheels sollen mindestens Größen wie folgende bereitstellen:
runnableTasks
waitingTasks
activeWorkers
queuePressure
targetRate
actualRate
handlerDuration
overrunCount
Das konkrete Metrikformat ist nicht normativ.
5. RuntimeBus und Intrinsic-Grenze¶
5.1 Mutationsgrenze¶
Zustandsändernde Scheduler-Operationen laufen ausschließlich über den RuntimeBus.
Typische Operationen:
spawn
wait / yield
resume / wake
cancel
query cancellation
register / update EngineRuntimeConfig
native dispatch / native completion
park on native handle / wake native waiter
create / release affinity domain
callback inject
create / release affinity domain betrifft Scheduler und JME gemeinsam. Der Bus routet, er entscheidet nichts.
Mailbox-, Channel- und Actor-Logik liegen darüber.
5.2 Intrinsic-Encoding¶
Die Intrinsic-Grenze ist stabil und versioniert. Diese Scheduler-Spezifikation friert jedoch keine 16-Bit-ID-Bereiche oder Opcode-Nummern ein.
Gemäß VM-Spec bleiben zwei kompatible Lowering-Strategien zulässig:
- compiler-known Builtin/Intrinsic über den normalen Call-Pfad,
- ein generischer
Intrinsic-Opcode mit Subcode.
Konkrete IDs und Encoding gehören in die zentrale VM-/Intrinsic-Spezifikation.
5.3 JadeValue¶
Intrinsics umgehen das aktuelle Grenzmodell nicht.
Gemäß 11-jadevalue-und-register-layout ist JadeValue das Transportformat an Call-, Return-, Intrinsic- und FFI-Grenzen. Innerhalb einer Funktion arbeitet die VM auf dem statisch angelegten Register-Buffer.
Fast Paths sind zulässig, sofern sie dieselbe Semantik und dieselben Verifier-/ABI-Invarianten erhalten.
5.4 Capabilities¶
Capability-Prüfung ist keine Scheduler-Policy.
Runtime-Capabilities werden an RuntimeBus-/VM-Grenzen erzwungen. Der Scheduler erhält nur autorisierte Scheduler-Kommandos.
6. Normative Invarianten¶
S-1 Der Scheduler ist Teil der VM, kein Actor und kein Userland-Service.
S-2 Tasks werden M:N auf Worker-Threads ausgeführt; die Workerzahl ist konfigurierbar.
S-3 Die Task ist die kleinste suspendierbare Scheduler-Einheit; Actors liegen darüber.
S-4 Der Scheduler besitzt keinen globalen Heartbeat.
S-5 Wartende Tasks werden durch Events oder Zeitbedingungen wieder runnable.
S-6 Reduction-basierte Preemption schützt vor unbegrenzter Worker-Monopolisierung.
S-7 Preemption erfolgt nur an VM-definierten sicheren Punkten.
S-8 Suspension ist Runtime-Eigenschaft, keine eigene JDL-Funktionsklasse.
S-9 Für normale suspendierbare Aufrufe gibt es kein Async-Row-Element und keine notwendige async/await-Färbung.
S-10 Neue parallele Ausführung entsteht explizit durch Task-Erzeugung.
S-11 Schedulerzustand und Task-Ausgang sind getrennte Dimensionen.
S-12 Throw[E] unwindet nicht über Task-Grenzen; es wird beim Task-Ausgang materialisiert.
S-13 Cancellation ist weder Throw[E] noch Trap. Der Trap-Teardown wartet nicht auf kooperative Cancellation.
S-14 Der Scheduler kennt nur EngineRuntimeConfig, nicht die semantische Engine.
S-15 Timer-Wheels werden durch Engine-Runtime-Konfiguration aktiviert und parametrisiert.
S-16 Scheduler-Zustand wird ausschließlich über den RuntimeBus mutiert.
S-17 Tasks besitzen keine Scheduler-Mailbox; Messaging liegt oberhalb des Scheduler-Cores.
S-18 VM-Suspensionssignale sind keine JDL-Result[T,E]-Werte.
S-19 Intrinsic-Encoding und IDs werden zentral in VM-/Intrinsic-Spezifikationen festgelegt.
S-20 Capability-Enforcement liegt an RuntimeBus-/VM-Grenzen, nicht in der Scheduling-Policy.
S-21 Die beobachtbare Semantik einer Jade-Task hängt niemals von ihrer Worker-Zuordnung ab.
S-22 Thread-affine native Ausführung findet auf NativeExecutionLanes außerhalb des Worker-Pools statt.
S-23 Lane- und Pool-Threads führen keine Jade-Tasks aus.
S-24 Eine AffinityDomain ist für ihre gesamte Lebensdauer genau einem Host-Thread zugeordnet.
S-25 affinity = any mit execution = blocking läuft im NativeBlockingPool.
S-26 affinity = stable läuft unabhängig von execution auf der gebundenen Lane.
S-27 Stabile native Ausführung ist durch die Lane serialisiert; eine Exklusiv-Sperre ist dafür nicht nötig.
S-28 Bei affinity = any mit access = exclusive wartet ein fremder Token auf Freigabe; Wiedereintritt mit demselben Token trappt.
S-29 Der NativeEntryToken wird über synchrone Callbacks und deren strukturierte Kind-Tasks weitergegeben.
S-30 Der NativeEntryToken ersetzt keinen allgemeinen Wartegraphen; Deadlocks über lose Kommunikation werden nicht vollständig erkannt.
S-31 Ein laufender nativer Aufruf wird durch Cancellation nicht beendet; seine Holds bleiben bis zur echten Rückkehr.
S-32 Ein nativer Callback führt Jade-Code nur als Scheduler-Task aus, nie direkt auf einem nativen Thread.
S-33 Native Completions werden über den gewöhnlichen Wait-/Wakeup-Mechanismus zugestellt.
S-34 Der Scheduler besitzt keine Wahrheit über Handles; AffinityDomain und Exklusiv-Zustand eines Handles gehören der JME.
7. Bewusst offene Implementierungsdetails¶
Diese Punkte können später entschieden werden, ohne das semantische Modell zu ändern:
| Punkt | Offen |
|---|---|
| Worker-Default | Ableitung aus CPU-/Environment-Ressourcen |
| Work-Stealing | Deque, Steal-Größe, Victim-Auswahl |
| Event-Poller | Plattform-Backend |
| Wait-Registry | interne Datenstruktur |
| Timer-Wheel | Ebenen, Slots, Speicherlayout |
| Master Clock | eigener Thread oder äquivalente Integration |
| Task-Outcome | konkrete Repräsentation / Error-Envelope |
| Task-Handle | Join/Detach/Structured-Concurrency-Lifetime |
| Shutdown | Drain, Graceful Stop, Forced Stop |
| Intrinsic-ABI | ID-Breite, Nummern, Encoding |
| Metrics | genaue Struktur und Export |
| NativeBlockingPool | Threadzahl, Wachsen, Schrumpfen |
| NativeExecutionLane | Anzahl und Lebenszyklus |
| Lane-Placement | Zuordnung von AffinityDomains zu Lanes |
| Lane-Queue | konkrete Warteschlangenstruktur |
| Exklusiv-Warteschlange | wer zuerst geweckt wird, Fairness |
| NativeEntryToken | Repräsentation und Breite |
| Native Completion | interne Ereignisdarstellung |
| Deadlock-Diagnose | optionale Beobachtung des Wartegraphen |
Diese Fragen sind keine Blocker für das Scheduler-Grundmodell.
8. Inkrementeller Implementierungsweg¶
V1
ein Worker
eine Run Queue
Task-Zustandsautomat
Reduction-Counter
generisches wait / wake
Event-Poller
V2
mehrere Worker
Work-Stealing
Worker-Parking
V3
Master Clock
optionales Timer-Wheel
Sleep / Deadline / Timeout
V4
EngineRuntimeConfig
Engine-lokale Timer-Wheels
Resource Limits
Overrun-Policies
V5
Metrics
Scheduler-Introspection
Queue-/Fast-Path-Optimierungen
V6
NativeBlockingPool
native Completion → Wakeup
NativeExecutionLane
AffinityDomain-Zuordnung
V7
exklusive any-Handles
NativeEntryToken
synchroner Callback-Eingang
strukturierte Token-Weitergabe
V8
Lane-Placement-Heuristiken
Diagnose nativer Wartezustände
Introspection / Mission Control
Task-Outcome-Materialisierung für Throw[E], Trap und Cancellation muss spätestens mit Task-Join/Wait integriert werden.
Änderungsprotokoll¶
v0.3.0¶
- Worker-Unabhängigkeit der Task-Semantik geschärft (§1.1, S-21), ohne Ausnahme für FFI.
- Native Ausführung außerhalb der Worker eingeführt:
NativeExecutionLaneundNativeBlockingPool(§1.3). - Dispatch-Tabelle aus
affinityundexecution(§3.7);blockingüberstimmtstablenie. - AffinityDomain mit stabilem Host-Thread; Domain entsteht beim erzeugenden Aufruf (§3.8).
- Stabile Domains als bereits serialisiert festgehalten (§3.9); Exklusiv-Sperre nur für
any(§3.10). - Trap-Teardown wartet nicht auf kooperative Cancellation (§3.6, S-13), Auftrag aus
jade-fehlermodell§13. NativeEntryTokenim Task-Modell, Weitergabe über synchrone Callbacks und strukturierte Kinder, Grenze gegenüber allgemeiner Deadlock-Erkennung (§3.11).- Cancellation beendet laufende native Aufrufe nicht (§3.12).
- Callbacks laufen immer als Scheduler-Task (§3.13); Rückgabewert bei nicht erfolgreicher synchroner Callback-Task offen und an die FFI-Spec verwiesen.
- RuntimeBus-Operationen, Invarianten S-21 bis S-34, offene Implementierungsdetails und Implementierungsstufen V6 bis V8 ergänzt.
v0.2.0¶
- D-spezifische Implementierungsdetails entfernt; Host auf Zig aktualisiert.
Effect[R,E,D]und die alte Trennung „imperativer Stil / Effect-Stil“ entfernt.- Effect Rows
->{...}übernommen; Suspendierbarkeit davon ausdrücklich getrennt. - Task-State und Task-Outcome getrennt.
Throw[E]-Materialisierung an Task-Grenzen ergänzt.- Cancellation von
Throw[E]und Trap getrennt. - Task-Mailbox aus dem Scheduler-Core entfernt.
JadeResult.yield()als veraltete Vermischung von VM-Control und JDL-Resultbeseitigt.JadeValueals Intrinsic-Grenzformat berücksichtigt.- Capability-Enforcement vom Scheduler an RuntimeBus-/VM-Grenzen verschoben.
- feste Intrinsic-ID-Bereiche aus dieser Spezifikation entfernt.
- Timer-Wheel-Slotzahlen, Queue-Strukturen und Plattform-I/O zu Implementierungsdetails gemacht.
- Aufbau auf acht kompakte Abschnitte reduziert.