Flags

Flags are a synchronization mechanism which allow a thread to wait for a single condition or a combination of conditions. The conditions are represented by bits in a 32 bit word. Flags are inspired by the µITRON specification.

Flags are of type cyg_flag_t, which are 32 bit words, and routines are provided to set or mask some bits in the flag value.

A “consumer side” thread can wait for a “producer side” thread to set the entire collection of bits, or any subset of them.

When a thread sets some bits in a flag, all threads whose requirements are now satisfied are woken up; thus flags have broadcast semantics. A variation on the wait call can specify that the flag value be cleared when the wait call is satisfied, in which case the setting of bits would not be a broadcast.

Blocking, non-blocking, and “blocking with time-out” versions of the wait calls are provided.

void cyg_flag_init(cyg_flag_t *flag);

Initializes a flag variable.

void cyg_flag_destroy(cyg_flag_t *flag);

Destroys a flag variable.

void cyg_flag_setbits(cyg_flag_t *flag, cyg_flag_value_t value);

Sets the bits in flag which are set in value.

A side effect of cyg_flag_setbits() is that the kernel wakes up any waiting threads whose requirements are now satisfied.

flag

A pointer to the flag whose bits are being set. The new setting of flag will be *flag -> (*flag | value).

value

A word whose 1 bits will be also set in *flag.

void cyg_flag_maskbits(cyg_flag_t *flag, cyg_flag_value_t value);

Clear the bits in the given flag which are zero in the value. This cannot result in new threads being eligible for awakening.

flag

A pointer to the flag whose bits are being cleared. The new setting of flag will be *flag -> (*flag & value).

value

A word whose 0 bits will be also cleared in *flag.

We now describe the cyg_flag_wait(), which frequently uses the following macros:


 #define CYG_FLAG_WAITMODE_AND ((cyg_flag_mode_t)0)
 #define CYG_FLAG_WAITMODE_OR ((cyg_flag_mode_t)2)
 #define CYG_FLAG_WAITMODE_CLR ((cyg_flag_mode_t)1)

cyg_flag_value_t cyg_flag_wait(cyg_flag_t *flag, cyg_flag_value_t pattern, cyg_flag_mode_t mode);

Wait for all the bits which are one in pattern to be set in the flag value (if mode is CYG_FLAG_WAITMODE_AND) or for any of the bits which are one in pattern to be set in the flag value (if mode is CYG_FLAG_WAITMODE_OR).

When cyg_flag_wait() returns, meaning that the condition is met, the flag value which succeeded is returned from the call; in other circumstances (such as a bad value for mode or pattern), zero is returned to indicate the error.

If the mode is one of those above plus CYG_FLAG_WAITMODE_CLR, the whole of the flag value is cleared to zero when the condition is met.

cyg_flag_wait() takes the following parameters:

flag

The value of the flag (set by the thread that called cyg_flag_setbits() or cyg_flag_maskbits()) is placed in here.

pattern

The set of bits which, if set, will cause the calling thread to be woken up.

mode

A parameter which modifies the conditions for wake-up. It can take the following values:

CYG_FLAG_WAITMODE_AND

Only wake up if all the bits in mask is set in the flag.

CYG_FLAG_WAITMODE_OR

Wake up if any of the bits in mask is set in the flag.

CYG_FLAG_WAITMODE_AND + CYG_FLAG_WAITMODE_CLR, CYG_FLAG_WAITMODE_OR + CYG_FLAG_WAITMODE_CLR

Like CYG_FLAG_WAITMODE_AND and CYG_FLAG_WAITMODE_OR, but the entire flag is cleared to zero when the condition is met, whereas normally only the bits that are set in pattern would be cleared.

Waiting threads are queued depending on the semantics of the underlying scheduler. In release 1.2.1, this means that, if the multi-level queue scheduler is selected, queueing is in FIFO ordering, while the bitmap scheduler supports thread priority ordered queueing. When some flag value bits become signalled by a call to cyg_flag_setbits(), the queue is scanned in order, and each waiting thread in turn is awoken or re-queued depending on its request. When a thread is awoken, if it made the wait call with CYG_FLAG_WAITMODE_CLR, the flag value is cleared to zero, and the scan of queued threads is terminated.

cyg_flag_value_t cyg_flag_timed_wait(cyg_flag_t *flag, cyg_flag_value_t pattern, cyg_flag_mode_t mode, cyg_tick_count_t abstime);

A time-out version of cyg_flag_wait(). This waits for the condition required by pattern and mode to be met, or until the abstime time-out is reached, whichever is first. If the time-out is reached first, zero is returned. This call is only available if the configuration option CYGFUN_KERNEL_THREADS_TIMER (see the section called Option: Allow per-thread timers in Chapter 17) is enabled.

cyg_flag_value_t cyg_flag_poll(cyg_flag_t *flag, cyg_flag_value_t pattern, cyg_flag_mode_t mode);

A non-blocking version of cyg_flag_wait(). If the condition required by pattern and mode is met, the flag value is returned, otherwise zero is returned. The flag value may be cleared in the event of success by specifying CYG_FLAG_WAITMODE_CLR in the mode, as usual.

cyg_flag_value_t cyg_flag_peek(cyg_flag_t *flag);

Returns the current flag value.

cyg_bool_t cyg_flag_waiting(cyg_flag_t *flag);

Returns true if there are threads waiting on this flag.