41. Memory for a million sockets
A chat service must hold 1 million idle WebSocket connections. Each connection uses about 30 KB of server memory. Each server has 16 GB usable for connections. How many servers are needed at minimum?
- A.1
- B.4
- C.2
- D.30
Show answer
Answer: C. 2
1,000,000 x 30 KB = 30,000,000 KB, about 30 GB. With 16 GB per server, one is not enough and two give 32 GB. In practice add headroom for spikes and failover, for example an extra server, and tune buffers to lower per-connection memory.
42. Taking a mutex in an ISR
Why must an ISR never try to take an RTOS mutex that a task might hold?
- A.An ISR cannot block, and a mutex is owned by a task with priority inheritance, which has no meaning for an interrupt
- B.Mutexes are slower than semaphores
- C.ISRs cannot read global variables
- D.Mutexes are only for tasks with the same priority
Show answer
Answer: A. An ISR cannot block, and a mutex is owned by a task with priority inheritance, which has no meaning for an interrupt
If the mutex is held, a task would block until it is free, but an ISR cannot be suspended, so it would either fail or deadlock the system. Priority inheritance raises the holder's priority to the waiter's, and an interrupt is not a task. Defer the work to a task, or protect the data with a short critical section.
43. Is this task set schedulable
Three periodic tasks run under rate-monotonic priorities with execution time C and period T of (1 ms, 4 ms), (2 ms, 8 ms) and (3 ms, 12 ms). What does the Liu and Layland bound say?
- A.Total use is 75%, over the 69% bound, so it may fail
- B.Total use is 100%, so it cannot be scheduled
- C.Total use is 75%, under the 78% bound, so it is schedulable
- D.Total use is 50%, so priorities do not matter
Show answer
Answer: C. Total use is 75%, under the 78% bound, so it is schedulable
Utilisation is 1/4 + 2/8 + 3/12 = 0.75. The rate-monotonic bound for n tasks is n(2^(1/n) − 1), which for n = 3 is about 0.780. Since 0.75 ≤ 0.78, all deadlines are met. The 69% figure is the limit as n grows very large; passing it is enough, not necessary.
44. Parameter from a function that returns
What is wrong with this code?
void start_sensor(int id) {
sensor_cfg_t cfg = { .id = id, .rate = 100 };
xTaskCreate(sensor_task, "s", 256, &cfg, 3, NULL);
}- A.xTaskCreate copies the full struct, so the code is fine
- B.The task name must be at least 8 characters long
- C.A task priority of 3 is not allowed by the kernel
- D.cfg is on this function's stack and is gone once it returns
Show answer
Answer: D. cfg is on this function's stack and is gone once it returns
xTaskCreate only stores the pointer. If the new task runs after start_sensor returns, cfg has been overwritten by later calls. Use static storage, allocate the config for the task, or have the task copy it first and signal back before the function returns.
45. Two stack pointers in an RTOS on Cortex-M
In a FreeRTOS Cortex-M port, which stack pointer do tasks and ISRs use?
- A.Tasks and ISRs all share the MSP stack pointer
- B.ISRs use the PSP, and tasks use the MSP
- C.Tasks use PSP and own stacks; ISRs share the MSP
- D.Each ISR gets its own separate PSP stack
Show answer
Answer: C. Tasks use PSP and own stacks; ISRs share the MSP
Thread mode runs on the process stack pointer, which the kernel switches per task. Exceptions always use the main stack pointer. So ISR stack needs are paid once on the MSP, not added to every task stack, apart from the hardware frame pushed onto the task stack.
46. The Mars Pathfinder resets
The 1997 Mars Pathfinder lander kept resetting from watchdog timeouts. What was the root cause and fix?
- A.A stack overflow in one task; the stack was made bigger
- B.Radiation flipped memory bits; ECC memory was then added
- C.Clock drift in the timer; a spare crystal was switched in
- D.Priority inversion on a bus mutex; enabling inheritance fixed it
Show answer
Answer: D. Priority inversion on a bus mutex; enabling inheritance fixed it
A low-priority task held a mutex needed by a high-priority bus task, and medium-priority tasks kept the low one from running. The watchdog saw the high task miss its deadline and reset the system. Engineers enabled priority inheritance in VxWorks remotely.
47. Critical sections on FreeRTOS SMP
On FreeRTOS SMP, what does taskENTER_CRITICAL() do that a single-core build does not?
- A.It also takes kernel spinlocks, so the other core is kept out
- B.It disables interrupts directly on both cores at once
- C.It stops the clock of the other core until it exits
- D.Nothing extra; it only masks the local interrupts
Show answer
Answer: A. It also takes kernel spinlocks, so the other core is kept out
Masking interrupts only affects the local core. The SMP kernel adds spinlocks so that a critical section on one core excludes kernel critical sections on the other. The other core spins while waiting, so sections must be even shorter than on single core.
48. Inversion with a semaphore used as a lock
A team guards a shared flash driver with a binary semaphore instead of a mutex. Under load the high-priority task misses deadlines while a medium task runs. Why?
- A.Binary semaphores are much slower to take than mutexes are
- B.Binary semaphores have no inheritance, so the low holder is not boosted
- C.The flash driver disables all interrupts while it writes
- D.The medium task keeps stealing the semaphore from the high task
Show answer
Answer: B. Binary semaphores have no inheritance, so the low holder is not boosted
With no owner, the kernel cannot raise the priority of whoever took the semaphore. A medium-priority task can then preempt the low holder for a long time while the high task waits. Use a mutex for mutual exclusion.
49. Burst of runs after a long stall
A 10 ms task using vTaskDelayUntil was blocked for 100 ms by a higher-priority task. What does it do when it gets the CPU back?
- A.It skips the missed periods and waits 10 ms
- B.It runs several passes back to back to catch up
- C.It is deleted by the kernel for missing deadlines
- D.It waits 100 ms before running its next pass
Show answer
Answer: B. It runs several passes back to back to catch up
The wake time advances by 10 ms each call. If it is already in the past, the call returns at once, so the task loops quickly until its wake time is ahead of the tick count again. If catching up is harmful, check the return value and reset the wake time to now.
50. Seeing queue contents in a debugger
Your debugger plugin shows queues only as addresses. How can you make them show by name in the RTOS view?
- A.Name each queue variable with a q_ prefix
- B.Create all queues from inside the idle task
- C.Create queues only with xQueueCreateStatic
- D.Register each queue with vQueueAddToRegistry
Show answer
Answer: D. Register each queue with vQueueAddToRegistry
The queue registry is a small table that kernel-aware debuggers read to label queues and semaphores. It is only for debugging and costs a little RAM. It has no effect on behaviour.
51. Float use in tasks on Cortex-M4F
On a Cortex-M4F FreeRTOS port, several tasks use floats. What must be true for this to work safely?
- A.Only one task may ever use the FPU on this core
- B.Floats may only be used inside critical sections
- C.The FPU must be turned off inside every ISR
- D.The port saves FPU registers per task; stacks need room
Show answer
Answer: D. The port saves FPU registers per task; stacks need room
The CM4F port saves the high FPU registers in its context switch when a task has used the FPU, using the EXC_RETURN bits to decide. That adds up to about 136 bytes per task frame (72 stacked by hardware plus 64 by the port). Undersized stacks in float-heavy tasks overflow more easily.
52. Lowest-latency interrupts in Zephyr
A Zephyr app needs the lowest possible latency for one interrupt and the handler does not call kernel APIs. What does Zephyr offer?
- A.A cooperative thread at priority -16
- B.A k_work item submitted with K_NO_WAIT
- C.A k_timer running with a 1 µs period
- D.A direct ISR, or a zero-latency IRQ flag
Show answer
Answer: D. A direct ISR, or a zero-latency IRQ flag
Direct ISRs skip the common interrupt wrapper, and with CONFIG_ZERO_LATENCY_IRQS an IRQ can sit above the kernel lock level so irq_lock does not delay it. Like FreeRTOS high-priority ISRs, such handlers must not call kernel services that assume normal ISR context.
53. Limit on Zephyr mutex priority boost
In Zephyr, a cooperative thread waits on a k_mutex held by a preemptible thread. What limits how far the holder can be boosted?
- A.Zephyr mutexes never boost the priority of the holder
- B.The holder is always boosted to priority -16 at once
- C.CONFIG_PRIORITY_CEILING caps how far inheritance can raise it
- D.Only the idle thread is ever boosted by a mutex
Show answer
Answer: C. CONFIG_PRIORITY_CEILING caps how far inheritance can raise it
Zephyr k_mutex supports priority inheritance, but the raised priority is capped by CONFIG_PRIORITY_CEILING. Setting it to 0, for example, stops a preemptible holder from being boosted into the cooperative range. Check this value when mixing cooperative and preemptive threads.
54. Using a Zephyr condition variable
Which pattern is correct for waiting on a Zephyr k_condvar?
k_mutex_lock(&m, K_FOREVER);
while (!ready) {
k_condvar_wait(&cv, &m, K_FOREVER);
}
use_data();
k_mutex_unlock(&m);- A.Call k_condvar_wait without holding the mutex
- B.Test the condition once with if instead of while
- C.This: test the condition in a loop with the mutex held
- D.Signal the condvar first, then lock the mutex
Show answer
Answer: C. This: test the condition in a loop with the mutex held
k_condvar_wait releases the mutex while waiting and takes it back before returning. Another thread may change the condition before this one runs, so the condition must be checked again in a loop. The signalling side should change ready while holding the same mutex.
55. Catching thread stack overflow in Zephyr
Which Zephyr option uses the MPU to fault the moment a thread overflows its stack?
- A.CONFIG_THREAD_NAME
- B.CONFIG_HW_STACK_PROTECTION
- C.CONFIG_LOG_MODE_DEFERRED
- D.CONFIG_TIMESLICING
Show answer
Answer: B. CONFIG_HW_STACK_PROTECTION
Hardware stack protection places an MPU guard at the end of each thread stack, or uses stack limit registers on Armv8-M. An overflow triggers a fault at the bad access, and the fatal handler reports which thread. CONFIG_STACK_SENTINEL is a cheaper software check.
56. Time slicing in Zephyr
With CONFIG_TIMESLICING=y and CONFIG_TIMESLICE_SIZE=10, two preemptible Zephyr threads at priority 5 never sleep. What happens?
- A.The first thread keeps the CPU until it blocks
- B.Both are raised to priority 4
- C.Time slicing applies only to cooperative threads
- D.They alternate about every 10 ms
Show answer
Answer: D. They alternate about every 10 ms
Time slicing lets equal-priority preemptible threads share the CPU in slices of the set size in milliseconds. Without it, a thread runs until it blocks or yields. Cooperative threads are never sliced, and CONFIG_TIMESLICE_PRIORITY limits which priorities slicing applies to.
57. Aborting a thread that holds a mutex
A Zephyr supervisor calls k_thread_abort on a worker that currently holds a k_mutex. What problem follows?
- A.Zephyr releases the mutex for the thread automatically
- B.The mutex is never released, so its waiters block forever
- C.The supervisor thread is aborted along with the worker
- D.The mutex turns into a semaphore that anyone can give
Show answer
Answer: B. The mutex is never released, so its waiters block forever
Aborting a thread stops it at once without running cleanup, so locks, buffers and peripheral states it owned stay as they were. Waiters on that mutex hang. Prefer asking threads to exit through a flag or event, and let them release resources first.
58. Setting configMAX_PRIORITIES to 64
A developer sets configMAX_PRIORITIES to 64 "just in case", but uses only 6 levels. What is the cost on a typical port?
- A.Tasks above priority 32 can never be scheduled
- B.The tick rate drops by half to cover the levels
- C.There is no cost of any kind on any port
- D.More ready lists in RAM, and a slower priority search
Show answer
Answer: D. More ready lists in RAM, and a slower priority search
The kernel keeps one ready list per priority, so more levels use more RAM. Without configUSE_PORT_OPTIMISED_TASK_SELECTION, finding the top ready task scans from the highest level down. The optimised Cortex-M selection uses CLZ but limits you to 32 priorities.
59. Debugger shows only one call stack
The board halts in a HardFault, and the debugger shows only the fault handler and current task stack. How do you see what every task was doing?
- A.Turn on RTOS-aware debugging so it reads each task context
- B.Single-step through each task one at a time to see them
- C.Make every task stack bigger and run the test again
- D.Turn off the scheduler before halting the processor
Show answer
Answer: A. Turn on RTOS-aware debugging so it reads each task context
An RTOS plugin in tools like Ozone, Cube IDE or OpenOCD with GDB reads the kernel task lists and saved stack pointers. It rebuilds each task call stack and state. That often shows the task that corrupted memory before the fault.
60. Active object design in an RTOS
In the active object pattern, each task owns its data, waits on its own event queue and handles one event at a time. What is the main benefit?
- A.Tasks no longer need any stack memory at all
- B.Every event handler runs inside an ISR instead
- C.Little shared data and few locks remain, so races are rarer
- D.The scheduler is no longer needed by the system
Show answer
Answer: C. Little shared data and few locks remain, so races are rarer
Each object owns its state and others only send it events, so there is little shared memory to protect. Run-to-completion handling makes behaviour easier to reason about. The cost is queue RAM and thinking in events, which frameworks like QP help with.