# Research note: RTEMS SuperCore **Kind:** Read-only source analysis, 2026-10-07, on a sparse shallow clone of RTEMS/rtems at commit `b3a3b372fa8d` (cpukit/score/, cpukit/include/rtems/score/, cpukit/rtems/src/, cpukit/include/rtems/rtems/). Citations are relative to `cpukit/`; `S/` is `include/rtems/score/`, `R/` is `include/rtems/rtems/`. Line numbers drift; paths and symbols are the durable reference. Synthesized in `R-001`. --- ## Q1 Scheduler - Plugin interface `Scheduler_Operations` (S/scheduler.h:62-311): initialize, schedule, yield, block, unblock, update_priority, map and unmap_priority, node_initialize and destroy, release_job and cancel_job (EDF hooks), start_idle, and SMP-only ask_for_help, reconsider_help_request, withdraw_node, make and clean_sticky, pin and unpin, add and remove_processor, set_affinity. `Scheduler_Control` is {context, Operations, maximum_priority, name, is_non_preempt_mode_supported} (S/scheduler.h:337-366). Selection is a const table `_Scheduler_Table[]` and `_Scheduler_Count` plus `_Scheduler_Initial_assignments[]` with PROCESSOR_MANDATORY or OPTIONAL (S/scheduler.h:378-449), emitted by `confdefs/scheduler.h` (include/rtems/confdefs.h:79). - Deterministic Priority: `Scheduler_priority_Context` is a 16x16 `Priority_bit_map_Control` plus `Chain_Control Ready[]` (S/schedulerpriority.h:81-96; S/prioritybitmap.h:58-76); highest is find-first-bit on the major then minor word via `__builtin_clz` or `_CPU_Bitfield_Find_first_bit` (S/prioritybitmapimpl.h:75-82, 208-219). The Simple scheduler is one ordered chain (S/schedulersimple.h:83-93). - EDF: an RB-tree `Ready`; the node holds a `Priority_Control` (S/scheduleredf.h:83-113). A deadline is just another priority: `release_job` does `_Thread_Priority_changed` or `add` with `SCHEDULER_PRIORITY_MAP(deadline)`; non-deadline threads carry `SCHEDULER_EDF_PRIO_MSB` (bit 63) so they sort as background (score/src/scheduleredfreleasejob.c:45-98; S/scheduleredfimpl.h:55-61). CBS extends EDF with budget-overrun servers (S/schedulercbs.h:109-159). - `Priority_Control` is `uint64_t` (S/priority.h:91); `SCHEDULER_PRIORITY_MAP` shifts left by 1, reserving the LSB as the FIFO or LIFO "append" bit (S/schedulernodeimpl.h:65-70). - SMP: `Scheduler_SMP_Context` adds a `Scheduled` chain beside the ready structure; node states BLOCKED, SCHEDULED, READY with Graphviz state diagrams in the header (S/schedulersmp.h:61-121; S/schedulersmpimpl.h:44-120). Priority SMP is G-FP; Priority Affinity SMP admits it "does not honor that affinity" yet (S/schedulerpriorityaffinitysmp.h:about 50-56); EDF SMP keeps per-processor affine RB queues, index 0 is one-to-all (S/scheduleredfsmp.h:59-136); Strong APA (Cerqueira et al.) does BFS backtracking over CPUs in the affinity set (S/schedulerstrongapa.h:58-67, 99-140). - `Scheduler_Node` is {owner, user (owner or idle), idle placeholder, sticky_level, Wait.Priority aggregation, request queue} (S/schedulernode.h:94-229). One node per scheduler instance per thread: `Thread_Scheduler_control` {nodes, Wait_nodes, Scheduler_nodes, helping_nodes, pin_level, Affinity} (S/thread.h:297-420). - Helping: `_Scheduler_SMP_Ask_for_help` preempts the lowest scheduled node or parks the node READY (S/schedulersmpimpl.h:1592-1700); requests are appended to `Per_CPU_Control::Threads_in_need_for_help` with `dispatch_necessary=true` (S/schedulersmpimpl.h:610-640) and drained in `_Thread_Preemption_intervention` on the next dispatch (score/src/threaddispatch.c:176-213). - Dispatch: `Per_CPU_Control` holds isr_nest_level, isr_dispatch_disable, thread_dispatch_disable_level, `volatile bool dispatch_necessary`, executing, heir (S/percpu.h:406-473). `_Thread_Dispatch_enable` dispatches only on the 1 to 0 transition when `dispatch_necessary` (threaddispatch.c:375-400); `_Thread_Do_dispatch` loops heir to executing, calls `CPU_budget.at_context_switch`, `_Context_Switch`, repeats while `dispatch_necessary`, then runs post-switch actions with level 0 (threaddispatch.c:278-358). A remote heir change is an atomic message plus IPI (S/threaddispatch.h:270-283). - Idle: `_Thread_Idle_body` defaults to the port `_CPU_Thread_Idle_body` (score/src/threadidledefault.c:44; score/cpu/no_cpu/include/rtems/score/cpu.h:1050); idle threads also serve as placeholders for sticky and ceiling nodes across scheduler instances (S/schedulernode.h:122-132). - Effective priority: `Priority_Aggregation` is an RB-tree `Contributors` plus a `Node` whose `.priority` mirrors the minimum (S/priority.h:112-198); `_Priority_Insert`, `Extract`, `Changed` rewrite `Node.priority` only when the minimum changes (S/priorityimpl.h:565-741). A thread's `Real_priority` node (S/thread.h:about 863) is one contributor into its home scheduler node's `Wait.Priority`; ceilings, inherited queue minima, and EDF deadlines are further nodes. `_Thread_Priority_apply` seeds one action and `_Thread_Priority_do_perform_actions` pushes the result into `_Scheduler_Node_set_priority` (score/src/threadchangepriority.c:53-65, 284-336). ## Q2 Context switch and interrupts - `_Context_Switch` calls the port `_CPU_Context_switch`; FP is lazily switched (`CPU_USE_DEFERRED_FP_SWITCH`) with `_Thread_Save_fp` and `_Restore_fp` around the switch (S/context.h:137-183; no_cpu cpu.h:207, 1068-1143; threaddispatch.c:about 328-336). - Two orthogonal levels: an `ISR_Level` cookie saved in a local by `_ISR_Local_disable`, `enable`, `flash` wrapping `_CPU_ISR_Disable` (S/isrlevel.h:60-118), and the per-CPU `thread_dispatch_disable_level`, which is the scheduler lock: `_Thread_Dispatch_disable*` increments (S/threaddispatch.h:183-222), `_Thread_Dispatch_enable` decrements (threaddispatch.c:375-400). - `ISR_lock_Control` wraps `SMP_lock_Control`; on UP it degrades to interrupt disable and `ISR_LOCK_NEEDS_OBJECT` removes the object entirely (S/isrlock.h:54-106). - SMP locks: a ticket lock (`fetch_add next_ticket`, spin on `now_serving`, release stores +1) (S/smplockticket.h:60-197); an MCS queue lock (exchange tail, spin on own `locked`, CAS on release) (S/smplockmcs.h:60-280); a Boehm-style seqlock (S/smplockseq.h). `SMP_lock_Control` defaults to the ticket lock with optional stats (S/smplock.h:86-119). - Interrupt exit: the port's `_ISR_Handler` (S/isr.h:163-174) consults `_Thread_Dispatch_necessary`, `_ISR_Nest_level`, and `isr_dispatch_disable` (S/percpu.h:402-437, 903-906) and calls `_Thread_Dispatch`, which sets the level 0 to 1 and runs `_Thread_Do_dispatch` (score/src/threadplaindispatch.c:43-57). `RTEMS_SCORE_ROBUST_THREAD_DISPATCH` faults with `INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT` if interrupts are disabled at dispatch (threaddispatch.c:282-292; S/threaddispatch.h:64). - Interrupt stacks: per-CPU `interrupt_stack_low` and `high` carved from the configured `_ISR_Stack_area_begin` and `_ISR_Stack_size` (S/percpu.h:395-400; S/isr.h:101-125; score/src/isr.c:58-78). `CPU_HAS_SOFTWARE_INTERRUPT_STACK` is gone from the template port; every port now gets the per-CPU stack fields. - ISR misuse: `_ISR_Is_in_progress` via the nest level or a port hook (S/percpu.h:722-728; cpu.h:555). Blocking sends from an ISR return `STATUS_MESSAGE_QUEUE_WAIT_IN_ISR` (score/src/coremsgsubmit.c:139-142), which maps to `RTEMS_CALLED_FROM_ISR = 18` (R/status.h:187). ## Q3 Time - `Watchdog_Control` is an RB node, cpu, routine, 64-bit `expire` (S/watchdog.h:110-138); `Watchdog_Header` caches `first` (leftmost) (S/watchdog.h:91-102). `_Watchdog_Insert` descends while tracking whether the new node becomes first (score/src/watchdoginsert.c:41-81); `_Watchdog_Remove` advances `first` via `_Watchdog_Next_first` (watchdogremove.c:41-56); `_Watchdog_Do_tickle` fires all `expire <= now` under the per-CPU lock (watchdogtick.c:46-74). - Per CPU: `Watchdog {Lock, uint64_t ticks, Header[TICKS, REALTIME, MONOTONIC]}` (S/percpu.h:345-376, 494-514). `_Watchdog_Tick`: the boot CPU bumps `_Watchdog_Ticks_since_boot`, tickles TICKS with `++ticks`, MONOTONIC with `_Timecounter_Getnanouptime`, REALTIME with bintime, then `CPU_budget.at_tick` (watchdogtick.c:76-156). Clock headers key on `seconds<<30 | ns` (`WATCHDOG_BITS_FOR_1E9_NANOSECONDS`, S/watchdogimpl.h:427, 528-586). - The timecounter is FreeBSD's: `_Timecounter_Install`, `Tick`, `Bintime`, `Getnanouptime`, `Set_NTP_update_second`, `Discipline` (S/timecounter.h:65-320); `kern_tc.c` is outside this sparse clone. Simple counters use `_Timecounter_Tick_simple` (S/timecounter.h:242). - Strictly tick-driven: `CONFIGURE_MICROSECONDS_PER_TICK` gives `_Watchdog_Microseconds_per_tick` (include/rtems/config.h:527; S/watchdogticks.h:76-108). No tickless support anywhere in score (grep for "tickless" is empty). - Thread timeouts: `Thread_Timer_information {Lock, header, Watchdog}` (S/thread.h:566-572). `_Thread_queue_Add_timeout_ticks`, `monotonic`, `realtime`, `by_clock_id` pick the header; an absolute time already past yields immediate `_Thread_Continue(STATUS_TIMEOUT)`, an invalid timespec gives `STATUS_INVALID_NUMBER` (score/src/threadqtimeout.c:48-170); `_Thread_Timeout` is just `_Thread_Continue(STATUS_TIMEOUT)` (score/src/threadtimeout.c:101-111). - Rate monotonic: `Rate_monotonic_Control {Timer, state, Priority node, owner, Statistics, postponed_jobs, latest_deadline}` (R/ratemondata.h:89-153); states INACTIVE, ACTIVE, EXPIRED (R/ratemon.h:96-110). `rtems_rate_monotonic_period`: non-owner gives `RTEMS_NOT_OWNER_OF_RESOURCE`; `RTEMS_PERIOD_STATUS` returns `RTEMS_TIMEOUT` if EXPIRED; ACTIVE blocks (`STATES_WAITING_FOR_PERIOD`) until the watchdog fires; EXPIRED or `postponed_jobs>0` returns `RTEMS_TIMEOUT` immediately and renews (rtems/src/ratemonperiod.c:243-400). The timeout increments `postponed_jobs` and sets EXPIRED when the owner is not blocked (rtems/src/ratemontimeout.c:46-116). Statistics: count, missed_count, min, max, total CPU and wall time (ratemonperiod.c:158-212). Each period release calls `_Scheduler_Release_job`, so EDF deadlines come from this manager (ratemonperiod.c:108-135). - Timer server: the watchdog routine moves the timer onto a `Pending` chain and sends a system event; the server task runs routines in task context (rtems/src/timerserver.c:71-160); `rtems_timer_server_fire_after` uses class `TIMER_INTERVAL_ON_TASK` (rtems/src/timerserverfireafter.c:64). ## Q4 Blocking and waiting - `Thread_queue_Queue {ticket Lock, heads, owner, name}` (S/threadq.h:434-468). `Thread_queue_Heads` is a union: a FIFO chain, or a chain of per-scheduler `Thread_queue_Priority_queue`, each holding a `Priority_Aggregation Queue` (S/threadq.h:356-432). `Thread_queue_Operations {priority_actions, enqueue, extract, surrender, first}` (S/threadq.h:561-610) with FIFO, priority, and priority_inherit tables (score/src/threadqops.c:160-218, 369-690, 693-1424). Because the queue itself is an aggregation, its minimum becomes a contributor to the owner (threadqops.c:1041-1067). - `_Thread_queue_Enqueue` (score/src/threadqenqueue.c:411-498): claim wait, `Path_acquire`, `ops->enqueue`, set `INTEND_TO_BLOCK`, disable dispatch, release the queue lock, run `enqueue_callout` (arms the timeout), `_Thread_Set_state`, then CAS `INTEND_TO_BLOCK` to `BLOCKED`; if the CAS fails a surrender or timeout already set READY, so it removes the timer and unblocks; finally `_Thread_Dispatch_direct`. - Wait flags: READY 0, INTEND_TO_BLOCK 1, BLOCKED 2 plus class bits EVENT, SYSTEM_EVENT, OBJECT, PERIOD (S/threadimpl.h:2259-2307), changed by atomic CAS (S/threadimpl.h:2426-2431). Wakers try `INTEND_TO_BLOCK` to READY; if that fails the thread is BLOCKED so they set READY and `_Thread_Unblock` (threadtimeout.c:45-99; threadqenqueue.c:597-630). - Deletion with waiters: `_Thread_queue_Flush_critical` with a filter that writes `STATUS_OBJECT_WAS_DELETED` or `STATUS_UNAVAILABLE` into `Wait.return_code` (score/src/threadqflush.c:49-90), used by semaphore destroy and barriers (S/coresemimpl.h:123-126; S/corebarrierimpl.h:163-182). - Events: a 32-bit `rtems_event_set`, `RTEMS_ALL_EVENTS` (R/event.h:96-436); seize and surrender reuse the wait-flag machine without a thread queue (rtems/src/eventseize.c:87-122; eventsurrender.c:102-140); system events are a separate class. - Condition variables: self-contained `_Condition_Wait*` on a FIFO queue, releasing the mutex inside the enqueue callout (score/src/condition.c:55, 120-175). ## Q5 Synchronization and PI - `CORE_mutex_Control` is a thread queue; recursive adds `nest_level`; ceiling adds a `Priority_ceiling` node and scheduler (S/coremutex.h:74-118). The slow seize enqueues with a deadlock callout (score/src/coremutexseize.c:47-75); surrender via `_Thread_queue_Surrender` (S/coremuteximpl.h:285-320); ceiling ownership adds the ceiling node to the owner, `STATUS_MUTEX_CEILING_VIOLATED` otherwise (S/coremuteximpl.h:431-461). - PI is `_Thread_queue_Operations_priority_inherit` (S/coremuteximpl.h:61): enqueue inserts the waiter's node into the queue aggregation; a new minimum generates an action on the owner's scheduler node and `_Thread_Priority_perform_actions(owner)` (threadqops.c:989-1067). - Transitive: yes. `_Thread_Priority_perform_actions` loops: apply actions to `the_thread`; if actions remain, `the_thread = the_thread->Wait.queue->owner` and repeat (score/src/threadchangepriority.c:227-282). Inside, `_Thread_Priority_do_perform_actions` calls `operations->priority_actions` of the queue the current thread waits on, so an owner that is itself blocked on a PI mutex regenerates actions for the next owner (threadchangepriority.c:127-225). On SMP the whole owner chain is locked first by `_Thread_queue_Path_acquire`, which collects one `Thread_queue_Link` per hop (threadchangepriority.c:302-313; threadqenqueue.c:273-383). - MrsP: a ceiling priority per scheduler instance (S/mrsp.h:77-92), waiters spin-wait "sticky" via `_Thread_queue_Enqueue_sticky` and `_Thread_Priority_update_and_make_sticky`; a preempted owner borrows a waiter's processor through the helping protocol (S/mrsp.h:about 50-66; S/mrspimpl.h:363-410; threadqenqueue.c:500-575). A recursive seize is `STATUS_DEADLOCK` (S/mrspimpl.h:459). OMIP-style migratory inheritance is what the per-instance `Wait_nodes` and `helping_nodes` deliver for PI mutexes across clusters (S/thread.h:356-420). - Semaphore variants derived from attributes: counting, simple binary, binary mutex with no protocol, inherit, ceiling, or MrsP (rtems/src/semcreate.c:95-125; R/semimpl.h:65-72); `STATUS_MAXIMUM_COUNT_EXCEEDED` on counting overflow (S/coresemimpl.h:148-175). - Barrier: automatic release at `maximum_count` returns `STATUS_BARRIER_AUTOMATICALLY_RELEASED` (score/src/corebarrierwait.c:76-100); manual release is a flush. ## Q6 IPC and memory - Message queue: preallocated buffers, `Pending_messages`, `notify_handler` (S/coremsg.h:117-164); a buffer carries `size` and `int priority` (S/coremsgbuffer.h:64-89). Send appends (`INT_MAX`), urgent prepends (`INT_MIN`), priority inserts ordered (S/coremsgimpl.h:67-75; score/src/coremsginsert.c:82-103); a waiting receiver gets a direct copy (coremsgsubmit.c:about 85-150). - Partition: fixed-size buffers threaded as a chain by `_Chain_Initialize` (R/partdata.h:57-106; rtems/src/partcreate.c:68-76). Region: `Heap_Control` plus a FIFO or priority thread queue, `STATES_WAITING_FOR_SEGMENT`, waiters retried by `_Region_Process_queue` after each free (R/regiondata.h:60-67; rtems/src/regiongetsegment.c:100-128; regionprocessqueue.c:46-87). - Heap: boundary-tagged blocks `prev_size` and `size_and_flag` with `HEAP_PREV_BLOCK_USED`, first-fit over a free list (S/heap.h:60-146, 278-348; score/src/heapallocate.c:217-290; S/heapfirstfitimpl.h). Optional `HEAP_PROTECTION` adds protector words, an owning task tag, and delayed frees (S/heap.h:50, 239-261). `_Protected_heap_*` wraps with the allocator mutex (score/src/pheapallocate.c:53-55). The workspace `_Workspace_Area` is a heap, optionally unified with the C heap (S/wkspace.h:59; S/wkspacedata.h:77-98). - Objects: a 32-bit id is class (5 bits at 27) | API (3 at 24) | node (8 at 16) | index (16) (S/object.h:101-174); `Objects_Information` with `local_table`, inactive chain, block extension for `OBJECTS_UNLIMITED_OBJECTS` (S/objectdata.h:198-312; S/object.h:180). `_Objects_Get` is a single unsigned "delta" range check, a local interrupt disable stored in the lock context, and a table lookup (score/src/objectgetlocal.c:44-80). - Configuration: `confdefs.h` includes topic headers (include/rtems/confdefs.h:61-81) that emit const objects consumed through `rtems_configuration_get_*` macros (config.h:392-840). Static by default, dynamic only via the unlimited flag. ## Q7 Isolation - No MPU or MMU task isolation: no MPU, MMU, or protection-domain references in score headers or the template port; the Memory Handler only distributes BSP-provided areas (S/memory.h:63-93, 308-334). Stack overflow is detected after the fact by the stack checker (include/rtems/stackchk.h:70-94; `RTEMS_FATAL_SOURCE_STACK_CHECKER`, S/interr.h:126); heap protection is a debug aid. - `rtems_task_mode` offers PREEMPT or NO_PREEMPT, TIMESLICE, ASR or NO_ASR, INTERRUPT_LEVEL (R/modes.h:83-256), implemented by toggling `is_preemptible`, `CPU_budget.operations`, ASR enable, and `_ISR_Set_level`; on SMP NO_PREEMPT needs scheduler support and interrupt-level changes are `RTEMS_NOT_IMPLEMENTED` (rtems/src/taskmode.c:67-155). Timeslicing is a pluggable `Thread_CPU_budget_operations` (S/threadcpubudget.h:86-94). ## Q8 Observability - Present in the clone: the capture engine (include/rtems/capture.h:53-413; per-thread hook S/thread.h:822-825), record infrastructure (S/percpu.h:638), `rtems_cpu_usage_report` and `reset` (include/rtems/cpuuse.h:123-169), the stack checker, and user extensions {create, start, restart, delete, switch, begin, exitted, fatal, terminate} (S/userext.h:253-263). - Per-thread CPU time: `cpu_time_used` updated on each heir change as the uptime delta against the per-CPU `cpu_usage_timestamp` (S/threadimpl.h:1260-1293; S/percpu.h:489). - Fatal: `Internal_errors_Source` (S/interr.h:63-179) and core codes including `THREAD_QUEUE_DEADLOCK=28`, `BAD_THREAD_DISPATCH_DISABLE_LEVEL=30`, `BAD_THREAD_DISPATCH_ENVIRONMENT=31` (S/interr.h:188-237). `_Terminate` disables interrupts, runs fatal extensions, marks the system terminated, halts in the idle body (score/src/interr.c:51-81). - Deadlock detection: `_Thread_queue_Path_acquire` walks owner to `owner->Wait.queue` to its owner; reaching the enqueuing thread is `THREAD_QUEUE_DEADLOCK_DETECTED`. On SMP each hop registers a `Thread_queue_Link` in a global RB-tree `_Thread_queue_Links`; `_Thread_queue_Link_add` finding a reverse edge is the cycle test, and `Thread_queue_Gate` ordering avoids deadlocking on the SMP locks themselves (score/src/threadqenqueue.c:65-175, 273-383; S/threadq.h:135-139). Enqueue then invokes `deadlock_callout`: `STATUS_DEADLOCK` for mutexes or fatal `INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK` (threadqenqueue.c:400-449; coremutexseize.c:57-60). ## Q9 Configuration, portability, quality - Port contract (score/cpu/no_cpu/include/rtems/score/cpu.h): feature macros `CPU_SIMPLE_VECTORED_INTERRUPTS`, `CPU_HARDWARE_FP`, `CPU_USE_DEFERRED_FP_SWITCH`, `CPU_ENABLE_ROBUST_THREAD_DISPATCH`, `CPU_STACK_GROWS_UP`, `CPU_CACHE_LINE_BYTES`, `CPU_MAXIMUM_PROCESSORS`, `CPU_STACK_MINIMUM_SIZE`, alignments (cpu.h:80-636); functions `_CPU_ISR_Disable`, `Enable`, `Flash`, `Set_level`, `Get_level`, `_CPU_Context_Initialize`, `switch`, `restore`, `save_fp`, `restore_fp`, `_CPU_Thread_Idle_body`, `_CPU_Bitfield_Find_first_bit`, `_CPU_Counter_read` and `frequency`, `_CPU_Exception_frame_print`, `_CPU_Spin_wait` (cpu.h:654-1362); cpuimpl.h adds the per-CPU control size, TLS variant, `_CPU_Get_current_per_CPU_control`, context validate and clobber (cpuimpl.h:58-204). Ten ports under score/cpu. - Configuration is `confdefs.h` plus per-topic headers (include/rtems/confdefs.h:61-81), compile-time only. - Quality discipline: SPDX BSD-2-Clause on every file (S/thread.h:1), dense Doxygen (248 tags in the 1,517-line S/threadqimpl.h), `_clang-format` at the repository root, and 34 files in the clone are "part of the RTEMS quality process and was automatically generated" from specification items (R/tasks.h:38-45, 423 `spec:/rtems/task/if/create`), the ESA pre-qualification toolchain. No `RTEMS_PRE_QUALIFIED` macro or test-name references appear in the clone. ## Q10 Synthesis RTEMS turns every priority influence (base, ceiling, inheritance, EDF deadline, MrsP ceiling) into a `Priority_Node` in a min-tree, so one algebra serves UP, SMP, and clustered scheduling; its lock-free wait-flag CAS, per-hop path locking, and cycle detection make blocking provably race- and deadlock-aware. The price is heavy abstraction, a large footprint, a tick-only clock, and no memory isolation. ## Ideas to borrow - Priority aggregation trees as the single effective-priority mechanism (S/priority.h:147-198; S/priorityimpl.h:565-741). - The INTEND_TO_BLOCK, BLOCKED, READY CAS state machine shared by queues, events, and periods (S/threadimpl.h:2259-2431; threadqenqueue.c:458-498). - Deadlock detection in PI chains with a status-or-fatal callout (threadqenqueue.c:273-383, 400-449). - Transitive PI via the owner-chain action loop (threadchangepriority.c:227-282). - Per-CPU watchdog headers with 64-bit expiry and a cached first node, separate tick, monotonic, and realtime trees (S/percpu.h:494-514; watchdoginsert.c:41-81). - The rate monotonic manager with postponed-job counting and CPU and wall statistics (ratemonperiod.c:158-212; ratemontimeout.c:46-66). - A scheduler plugin table selected at configuration time (S/scheduler.h:62-449). - MrsP sticky spin-wait plus helping (S/mrspimpl.h:363-410; threadqenqueue.c:500-575). - Flush filters that encode the wake reason into the waiter (threadqflush.c:49-90). - Spec-generated API headers with constraint blocks (R/tasks.h:38-45). ## Weaknesses - Complexity: a 1,575-line threadqops.c, a 919-line threadqenqueue.c, a 2,000-plus-line schedulersmpimpl.h; helping, sticky, and pinning interactions are hard to audit (S/thread.h:297-420). - Footprint: 64-bit priorities, per-scheduler nodes per thread, RB-trees everywhere, per-CPU locks and stats (S/percpu.h:384-641; S/schedulernode.h:94-229). - No isolation: no MPU or MMU domains; only after-the-fact stack checking (S/memory.h; include/rtems/stackchk.h). - Tick-only timing, no tickless idle (watchdogtick.c:76-156; config.h:527). - Configuration burden: dozens of `CONFIGURE_*` headers, compile-time static tables (include/rtems/confdefs.h:61-81). - Incomplete features: the affinity scheduler ignores affinity (S/schedulerpriorityaffinitysmp.h:about 50-56); SMP task modes return `RTEMS_NOT_IMPLEMENTED` (taskmode.c:67-81). - The global `_Thread_queue_Links` registry is a shared contention point on SMP (threadqenqueue.c:65-175).