FreeRTOS Event-Group Barriers: Define Participant Failure Before Using xEventGroupSync

A repeated barrier needs a policy for a participant that times out, skips a cycle or arrives after everyone else has abandoned it. xEventGroupSync() combines setting arrival bits with waiting for a mask; those bits do not carry a cycle number. Once a rendezvous can be abandoned, define how the application prevents arrivals from different cycles from satisfying the same mask.

This guide targets upstream FreeRTOS Kernel V11.1.0 task-context event groups. It focuses on repeated rendezvous and generation abandonment, not the general choice between notifications and event bits. Host tests described below used the official GCC POSIX port; target scheduling and product recovery remain untested.

Inspect what a successful rendezvous clears

The versioned event-group API describes synchronizing tasks by setting their bits and waiting for the complete mask. Test the returned mask for all required participant bits. Do not treat any nonzero result as success: it can contain only the arrivals that occurred before a timeout.

The V11.1.0 implementation clears the rendezvous mask when all required bits are present. Waiting tasks receive the event result associated with their unblock. A simple successful cycle therefore does not require every participant to manually clear its bit afterward.

Adding an unconditional clear after return can itself damage another cycle. One participant may already be entering the next rendezvous while another clears the shared mask based on the old one. Keep ownership of reset operations explicit rather than scattering clears among participants.

Follow the incomplete timeout path

When the wait times out without a complete mask, the implementation does not automatically remove the caller’s earlier arrival bit. That retained bit is the critical failure boundary. A later participant can complete the mask even though the original participant no longer considers that generation active.

There is also a scheduling boundary inside timeout handling: after a task becomes ready because its wait expired, another task may set the remaining bits before it executes. The source rechecks the current bits and clears the rendezvous mask if complete. Consequently, the returned mask is not a precise timestamped proof that every participant arrived before an application deadline.

Barrier failure trace: A sets bit 01 and times out with the bit retained; a late B adds bit 10 and satisfies 11 although A has abandoned the generation. A coordinator gate requires all old participants to exit before reset and reopening.
Arrival bits have no generation identity. A complete mask needs the application’s current-generation agreement before it can authorize shared work.

Reproduce the retained-arrival problem

Use two synthetic participant bits, A equal to 0x01 and B equal to 0x02, with required mask 0x03. These small values are illustrative application bits, not a complete allocation scheme for an event group.

  1. Start a fresh group with no bits set. Call sync for A with a finite wait while B does not arrive.
  2. After A returns, record the return mask and current group bits. Confirm that the required mask was incomplete.
  3. Mark generation G abandoned in the test’s application state. Then call sync for B without a blocking wait.
  4. Observe whether B receives the complete mask and the group clears it. Compare that kernel result with the application’s abandoned-generation record.
  5. Repeat with both participants arriving normally. Keep this positive control separate from the abandonment case.

A local C harness executed the timeout and late-arrival sequence against V11.1.0 using the POSIX port and GCC 14.2.0. A’s two-tick wait returned incomplete with its bit retained; the later B call returned the complete mask and cleared it. No wall-clock timing accuracy is claimed. The fixture demonstrates why matching bits alone cannot establish matching application generations.

Give one owner authority to commit or abandon

Before starting a generation, define its participant set and assign an application generation identifier. Each participant must associate its work and result with that identifier. Do not infer the generation from the event bits, and do not allow a task to quietly skip a required cycle while the others still expect it.

A coordinator can maintain a generation state such as collecting, committed, abandoned and retired. Participants report their outcome through a channel whose lifetime and capacity are defined independently. The coordinator serializes the decision that shared work may proceed. A participant returning a full mask must still check that its generation has not been abandoned before using other participants’ output.

This is a proposed application protocol, not an additional guarantee of xEventGroupSync(). If every participant is guaranteed to attend each cycle and abandonment is impossible by design, the extra failure protocol may be unnecessary. That assumption needs evidence and a stated response when a task fails.

Retire the old generation before reopening

  • Close admission for new calls using the old generation.
  • Notify participants of abandonment through the defined control path. Existing blocked sync calls need their own bounded exit or a separately verified cancellation design; merely clearing bits does not wake them successfully.
  • Collect acknowledgements that every old participant has left the old barrier path and cannot publish further arrivals or results for it.
  • Only then clear or recreate the barrier under its owner and admit the new generation.
  • If a participant cannot retire, keep the generation faulted and use the product’s approved recovery path. Elapsed time alone is not proof that stale writers disappeared.

Do not delete an event group while tasks may still use its handle and assume that application resources are safely retired. Likewise, rotating among a few groups does not solve the lifetime problem if a delayed participant can outlive the rotation and touch a reused object.

Hypothetical example and release tests

Imagine a hypothetical acquisition system combining two independently prepared calibration records. Task A reaches the barrier, times out and starts preparing a replacement record. Task B arrives late with the old record. The bits can complete while the two records describe different cycles, so the combined result would be invalid despite a complete mask.

A generation-aware coordinator rejects that combination and retires both old participants before admitting another cycle. Test normal completion, each participant missing, timeout near the last arrival, delayed old results, duplicate arrival attempts and a participant that never acknowledges retirement. Record generation, participant, returned mask and commit decision.

Acceptance means no mixed-generation result is committed, every abandonment reaches a defined terminal state, and barrier storage is never reused while old callers can access it. The host fixture covers the retained-bit mechanism only. It does not prove the coordinator, target timing or fault-recovery behavior of a finished product.

Similar Posts