Skip to content

user Synchronization

oguyon edited this page Jan 15, 2026 · 3 revisions

Synchronization Primitives {#page_Synchronization}

Effective management of concurrent processes and data streams requires robust synchronization. In the milk environment, this is achieved primarily through semaphores and various trigger modes managed via the PROCESSINFO structure and ImageStreamIO.


1. Semaphores

Semaphores are used to signal data availability or process completion.

1.1. Stream Semaphores

Each image stream in milk can have multiple semaphores. When a process finishes writing to a stream, it "posts" to these semaphores to notify downstream consumers.

  • Posting: processinfo_exec_end(processinfo) automatically posts to the stream's semaphores if configured.
  • Waiting: Consumer processes wait on a specific semaphore index of a stream. This is usually handled within the processinfo_loopstep(processinfo) call.

1.2. Process Semaphores

Processes can also use semaphores to coordinate directly. The PROCESSINFO structure includes mechanisms to wait for specific signals before proceeding with a loop iteration.


2. Trigger Modes

The PROCESSINFO structure allows a process to wait for a trigger before executing its loop body. This is typically configured via processinfo_waitoninputstream_init. The implementation handles various modes as defined in processtools_trigger.c.

2.1. Immediate (PROCESSINFO_TRIGGERMODE_IMMEDIATE)

The process does not wait. processinfo_waitoninputstream returns immediately with PROCESSINFO_TRIGGERSTATUS_RECEIVED. This is useful for free-running loops that do not depend on external events or timing.

2.2. Delay (PROCESSINFO_TRIGGERMODE_DELAY)

The process waits for a fixed time delay before proceeding.

  • Uses nanosleep to wait for the duration specified in processinfo->triggerdelay.
  • The status is set to PROCESSINFO_TRIGGERSTATUS_WAITING before the sleep and PROCESSINFO_TRIGGERSTATUS_RECEIVED after.

2.3. Counter polling (PROCESSINFO_TRIGGERMODE_CNT0, PROCESSINFO_TRIGGERMODE_CNT1, PROCESSINFO_TRIGGERMODE_CNT2)

The process polls the image stream counters to detect updates.

  • CNT0: Polls data.image[trigID].md[0].cnt0.
  • CNT1: Polls data.image[trigID].md[0].cnt1.
  • CNT2: Polls data.image[trigID].md[0].cnt2. This mode allows an external reader or controller to drive the loop flow by incrementing this specific counter.
  • The function enters a busy-wait loop (with usleep(5)) until the counter changes.
  • It calculates missed frames by comparing the new counter value with the previous one.

2.4. Semaphore (PROCESSINFO_TRIGGERMODE_SEMAPHORE)

This is the standard and most efficient synchronization mode for event-driven processing.

  • Initialization: Attempts to find an available semaphore index on the target stream using ImageStreamIO_getsemwaitindex.
  • Waiting:
    1. First, it tries ImageStreamIO_semtrywait to check if the semaphore is already posted.
    2. If not, it uses ImageStreamIO_semtimedwait to wait with a timeout (processinfo->triggertimeout).
  • Timeouts: If the wait times out, PROCESSINFO_TRIGGERSTATUS_TIMEDOUT is returned; otherwise, PROCESSINFO_TRIGGERSTATUS_RECEIVED.

2.5. Semaphore with Propagated Timeouts (PROCESSINFO_TRIGGERMODE_SEMAPHORE_PROP_TIMEOUTS)

Similar to the standard semaphore mode but explicitly handles timeout propagation logic, useful when chains of processes depend on each other and latency constraints must be respected.

2.6 Summary Table of Trigger Modes

Value Trigger Mode Description
0 PROCESSINFO_TRIGGERMODE_IMMEDIATE No waiting, returns immediately.
1 PROCESSINFO_TRIGGERMODE_CNT0 Trigger on cnt0 increment (image update).
2 PROCESSINFO_TRIGGERMODE_CNT1 Trigger on cnt1 increment (slice update).
3 PROCESSINFO_TRIGGERMODE_SEMAPHORE Wait for semaphore post (standard).
4 PROCESSINFO_TRIGGERMODE_DELAY Wait for a fixed time delay.
5 PROCESSINFO_TRIGGERMODE_SEMAPHORE_PROP_TIMEOUTS Semaphore wait with timeout propagation.
6 PROCESSINFO_TRIGGERMODE_CNT2 Trigger on cnt2 increment (external event).

3. Coordination with PROCESSINFO

The PROCESSINFO structure provides high-level functions that abstract the underlying synchronization:

  • processinfo_loopstart(): Initializes synchronization state for a loop.
  • processinfo_loopstep(): Wait for a trigger (as configured by the trigger mode) to start the next iteration.
  • processinfo_exec_start(): Marks the beginning of the computation block.
  • processinfo_exec_end(): Marks the end of computation, posting semaphores to notify downstream processes.

4. Monitoring Synchronization

You can monitor semaphores and process activity using:

  • milk-streamCTRL: Shows stream activity and semaphore counts.
  • milk-shmimmon <streamname>: Provides a real-time view of stream metadata, including semaphore status.
  • milk-procinfo: Lists active processes and their current synchronization state.

Clone this wiki locally