main
K12 — semaphores and task notifications
K12 separates three synchronization meanings behind small C++ wrappers:
BinarySemaphoreis an empty/full signal with no payload or owner;CountingSemaphore<Max>models a bounded count of available resources;TaskNotificationis a non-owning view of one task's TCB notification slot, with explicit action/value semantics.
Both semaphore wrappers use caller-owned static control blocks. The notification wrapper allocates no kernel object: its state is already inside the target task's TCB.
Hazard3 evidence
binary count 0 -> 1 -> 0
second binary give false (already full)
counting slots 2 -> 1 -> 0
third counting take waiter Blocked
one give wakes waiter; count consumed back to 0
notification take result 1
explicit overwrite value 0xA5A55A5A
The same high-priority waiter is observed in eBlocked for counting take,
notification take and value wait. vTaskSuspendAll creates a stable checkpoint
after notification give but before the waiter consumes the TCB value.
Build
make check
Debug
b synchronization_debug_checkpoint
p g_binary_initial_count
p g_binary_after_give
p g_binary_second_give
p g_counting_initial_count
p g_count_after_take1
p g_count_after_take2
p g_waiter_state_for_counting
p g_waiter_state_for_notification
p g_notification_pending_checkpoint
p g_notification_take_value
p/x g_notification_message_value
p g_sync_pass
Scope boundary
A semaphore is not payload storage. A notification has exactly one receiving
task per TCB slot and action/clear policy must be explicit; it is not a
multi-consumer queue. Binary/counting take and notify wait use different
state machines even when their visible wakeup looks identical.
Description
Languages
C++
54%
C
22.8%
Makefile
11.4%
Shell
8.3%
Assembly
2.4%
Other
1.1%