Event Flag
Categories:
6 minute read
Overview
When the system needs to handle many events, if each event is bound to a specific condition variable, and each condition variable is waited on by a thread, the system would require a large amount of memory to create condition variables and threads.
The event flag uses a bitmap to manage a group of events. Each bit in the bitmap represents an event. When one or more event states change, the corresponding bits change and wake up the waiting threads. Once awakened, the thread can retrieve the event states from the event bitmap.
- A thread can wait for event bits in the bitmap to be set to 1, or wait for event bits to be cleared to 0.
- A thread can wait for all event bits to be simultaneously set to 1 (logical AND relationship between events), or for any one bit to be set to 1 (logical OR relationship between events).
- A thread can wait for all event bits to be simultaneously cleared to 0 (logical AND relationship between events), or for any one bit to be cleared to 0 (logical OR relationship between events).
- A thread can choose whether to consume events. Consuming events means that when an event arrives and the thread is awakened, it can choose whether to clear the event.
- A thread can wait for event flag bits to toggle, which means a bit changes from 1 to 0, or from 0 to 1.
Event Flag Object and Object Descriptor
The event flag object is a derived class of XWOS Object struct xwos_object.
Similarly, event flag objects also use the event flag object descriptor xwos_flg_d
to solve the problems of validity and identity legitimacy.
The event flag object descriptor is composed of a pointer to the event flag object and a tag:
typedef struct {
struct xwos_flg * flg; /**< Pointer to the event flag object */
xwsq_t tik; /**< Tag */
} xwos_flg_d;
When referencing an object through the object descriptor, first check the value of obj->magic to see if it is 0x58574F53U, which confirms that the pointer obj points to a valid XWOS object.
Then compare the tags obj->tik and tik to see if they are equal, which confirms the object’s identity.
Since the object’s tik is globally unique, when the object is released, its tik will be destructed to 0 by the destructor.
When the memory address is reconstructed into a new object, its tik will definitely differ from the tik in the object descriptor.
Event Flag Initialization, Destruction and Dynamic Creation, Deletion
Static Initialization and Destruction
- Static initialization:
xwos_flg_init()- Static means the user predefines thread structure objects, which are allocated memory by the compiler at compile time.
- Destroy statically initialized event flag
xwos_flg_fini()
Dynamic Creation and Deletion
- Dynamic creation:
xwos_flg_create()- Dynamic means the program allocates memory through memory allocation functions at runtime and constructs the object on the allocated memory.
- Delete dynamically created event flag
xwos_flg_delete()
Generating Events
XWOS provides 6 CAPI for triggering events:
xwos_flg_s1m(): Set multiple event flag bits simultaneously, can be used in any contextxwos_flg_s1i(): Set a single event flag bit, can be used in any contextxwos_flg_c0m(): Clear multiple event flag bits simultaneously, can be used in any contextxwos_flg_c0i(): Clear a single event flag bit, can be used in any contextxwos_flg_x1m(): Toggle multiple event flag bits simultaneously, can be used in any contextxwos_flg_x1i(): Toggle a single event flag bit, can be used in any context
These CAPI not only modify the state of the event flag bitmap but also wake up all waiting threads through broadcast. The threads then compare the bitmap state to determine whether the event trigger condition has been satisfied. If the trigger condition is satisfied, the thread exits waiting; if not, it reenters the blocked waiting state.
Getting Event State
xwos_flg_get_num(): Get the total number of events in the event flagxwos_flg_read(): Directly read the event bitmap state. This function returns immediately and does not block.
Waiting for Events
xwos_flg_wait(): Wait for events, can only be used in thread contextxwos_flg_wait_to(): Timed wait for events, can only be used in thread contextxwos_flg_trywait(): Check for events, can be used in any context
Trigger Conditions
When calling the event wait CAPI, you need to specify a trigger condition (parameter: trigger). Trigger conditions are divided into level-triggered and edge-triggered.
Level-triggered
Level-triggered originates from digital circuits and is an analog concept. It refers to the trigger signal produced by a specific state (1 or 0) of the event bit. The following trigger conditions are all level-triggered:
XWOS_FLG_TRIGGER_SET_ALL: All event bits are set to 1XWOS_FLG_TRIGGER_SET_ANY: Any event bit is set to 1XWOS_FLG_TRIGGER_CLR_ALL: All event bits are cleared to 0XWOS_FLG_TRIGGER_CLR_ANY: Any event bit is cleared to 0
Edge-triggered
Edge-triggered originates from digital circuits and is an analog concept. It refers to the wakeup signal produced when the event state changes (from 1 to 0 or from 0 to 1). The following trigger conditions are edge-triggered:
XWOS_FLG_TRIGGER_TGL_ALL: All event bits toggleXWOS_FLG_TRIGGER_TGL_ANY: Any event bit toggles
Edge-triggered conditions require an initial state, just like digital circuits:
- When the initial value of a bit is 0 (low level), and it transitions to 1 (high level), that moment is called a rising edge. The triggered event is called rising-edge triggered.
- When the initial value of a bit is 1 (high level), and it transitions to 0 (low level), that moment is called a falling edge. The triggered event is called falling-edge triggered.
Clearing Events
- When using level-triggered mode, the event flag bits need to be cleared after reading the event bitmap, otherwise the events will remain in the triggered state.
You can specify the
actionparameter asXWOS_FLG_ACTION_CONSUMPTIONwhen calling the CAPI. The meaning of clear is:- When the thread is waiting for event bits to be set to 1, clear means clearing those bits to 0;
- When the thread is waiting for event bits to be cleared to 0, clear means setting those bits to 1;
- When using edge-triggered mode, there is no need to clear the event trigger condition.
Binding and Unbinding Signal Selector
The event flag can be bound to a signal selector via xwos_flg_bind().
When the awaited event occurs, the event flag sends a select signal to the signal selector. The signal selector then wakes up the waiting thread.
A bound event flag can be unbound via xwos_flg_unbind().
Event Flag Object Lifecycle Management
The base class of the event flag object is XWOS Object struct xwos_object.
The event flag object also has two sets of lifecycle management CAPI:
-
Access lifecycle management CAPI using object pointer: requires ensuring that the object is definitely valid when calling the CAPI, and there is no case of released-then-reallocated as another object.
xwos_flg_grab(): Increase reference count.xwos_flg_put(): Decrease reference count. When the reference count drops to 0, the garbage collection function is called to release the object.
-
Access lifecycle management CAPI using object descriptor: used when the user cannot guarantee that the object is definitely valid or cannot guarantee that the object has not become another object.
xwos_flg_acquire(): Determine that the object is valid and legitimate through the object descriptor, then increase the reference count.xwos_flg_release(): Determine that the object is valid and legitimate through the object descriptor, then decrease the reference count. When the reference count drops to 0, the garbage collection function is called to release the object.