EM-ODP  3.7.0
Event Machine on ODP
Events

Operations on an event. More...

Data Structures

struct  em_event_uarea_info_t
 Event user area information filled by em_event_uarea_info() More...
 
struct  em_event_vector_info_t
 Vector event information filled by em_event_vector_info() More...
 

Functions

em_event_t em_alloc (uint32_t size, em_event_type_t type, em_pool_t pool)
 
int em_alloc_multi (em_event_t events[], int num, uint32_t size, em_event_type_t type, em_pool_t pool)
 
void em_free (em_event_t event)
 
void em_free_multi (em_event_t events[], int num)
 
em_status_t em_send (em_event_t event, em_queue_t queue)
 
int em_send_multi (const em_event_t events[], int num, em_queue_t queue)
 
void * em_event_pointer (em_event_t event)
 
void * em_event_pointer_and_size (em_event_t event, uint32_t *size)
 Get a pointer to the event structure/data as well as the event size. More...
 
uint32_t em_event_get_size (em_event_t event)
 
em_pool_t em_event_get_pool (em_event_t event)
 Returns the EM event-pool the event was allocated from. More...
 
em_pool_t em_event_get_pool_subpool (em_event_t event, int *subpool)
 Returns the EM event-pool and subpool the event was allocated from. More...
 
em_status_t em_event_set_type (em_event_t event, em_event_type_t newtype)
 
em_event_type_t em_event_get_type (em_event_t event)
 
int em_event_get_type_multi (const em_event_t events[], int num, em_event_type_t types[])
 
int em_event_same_type_multi (const em_event_t events[], int num, em_event_type_t *same_type)
 
em_status_t em_event_mark_send (em_event_t event, em_queue_t queue)
 
em_status_t em_event_unmark_send (em_event_t event)
 
void em_event_mark_free (em_event_t event)
 Mark the event as "free". More...
 
void em_event_unmark_free (em_event_t event)
 Unmark an event previously marked as "free" (i.e mark as "allocated" again). More...
 
void em_event_mark_free_multi (const em_event_t events[], int num)
 Mark multiple events as "free". More...
 
void em_event_unmark_free_multi (const em_event_t events[], int num)
 Unmark multiple events previously marked as "free". More...
 
em_event_t em_event_clone (em_event_t event, em_pool_t pool)
 Clone an event. More...
 
em_event_t em_event_clone_part (em_event_t event, em_pool_t pool, uint32_t offset, uint32_t len, bool clone_uarea)
 Partially clone an event. More...
 
void * em_event_uarea_get (em_event_t event, size_t *size)
 Get a pointer to the event user area, optionally along with its size. More...
 
em_status_t em_event_uarea_id_get (em_event_t event, bool *isset, uint16_t *id)
 Get the event user area ID along with information if it has been set. More...
 
em_status_t em_event_uarea_id_set (em_event_t event, uint16_t id)
 Set the event user area ID. More...
 
em_status_t em_event_uarea_info (em_event_t event, em_event_uarea_info_t *uarea_info)
 Get the event user area information for a given event. More...
 
em_event_t em_event_ref (em_event_t event)
 
bool em_event_has_ref (em_event_t event)
 
void em_event_vector_free (em_event_t vector_event)
 Free the vector event only, not the events it contains. More...
 
uint32_t em_event_vector_tbl (em_event_t vector_event, em_event_t **event_tbl)
 Get the event vector table from an event of (major) type EM_EVENT_TYPE_VECTOR. More...
 
uint32_t em_event_vector_size (em_event_t vector_event)
 Number of event handles available (set) in a vector. More...
 
void em_event_vector_size_set (em_event_t vector_event, uint32_t size)
 Set the number of event handles stored in a vector. More...
 
uint32_t em_event_vector_max_size (em_event_t vector_event)
 Maximum number of event handles that can be stored in a vector. More...
 
em_status_t em_event_vector_info (em_event_t vector_event, em_event_vector_info_t *vector_info)
 Retrieve information about the given vector event. More...
 
uint64_t em_event_to_u64 (em_event_t event)
 

Detailed Description

Operations on an event.

All application processing is driven by events in the Event Machine. An event describes a piece of work or data to be processed. The structure of an event is implementation and event type specific: it may be a directly accessible buffer of memory, packet headers and data, a vector or user specified content etc.

Applications use the event type to interpret the event structure. The event type consists of a major and a minor part: the major part specifies the actual type or structure of the event (sw buf, packet, vector etc.) while the minor part is user specific and can be used to distinguish between different use cases of the event.

Events follow message passing semantics: an event has to be allocated using the provided API (em_alloc()) or received through queues by an EO callback function after which the event is owned by the application. Event ownership is transferred back to the system by using em_send() or em_free(). An event not owned by the application must not be touched.

The event handle, of type em_event_t, is not a direct pointer to the event structure, hence EM API functions must be used to get access to the contained data: for events of (major) type sw buffer or packet use em_event_pointer() while for vector events the contained array of event handles must be accessed with em_event_vector_tbl() instead. Use the (major part of the) event type to distinguish between vectors and other types of events.

Event References

Normally, each event is associated with one event handle (em_event_t) - each event allocation produces a new event (and associated payload data) that can be processed, sent or freed. When the user EO has allocated or received an event from a queue, the event payload data may be read and written as needed by the application. An exception to the above described scenario happens when using event references. An event reference is an additional event handle referring to an existing event. New references are created with the em_event_ref() API call. The intent of using multiple references is to avoid event copies. An event that has multiple references shares its data with the other reference handles and thus the (shared) data must not be modified. Reading event data from a reference is allowed. Writes to the event data must only be done when there is a single event handle left, i.e. when em_event_has_ref(event) returns 'false'. Results are undefined if these restrictions are not observed. The event is freed when the last reference, including the original event, is freed. It is not allowed to use event references with event groups since assigning an event that has references to an event group would assign all the references to the event group resulting in undefined behaviour. E.g. using em_send_group()/em_send_group_multi() to send a reference is wrong.

Event User Area

Additionally, an event may contain a user area separate from the event payload. The size of the event user area is set when creating the event pool from which the event is allocated. The user area is a fixed size (per pool) data area into which event related state data can be stored without having to access and change the payload. Note that the size of the event user area can be zero(0), depending on event pool configuration. Note also that the user area content is not initialized by EM, neither em_alloc() nor em_free() will touch it and thus it might contain old user data set the last time the area was used during a previous allocation of the same event. Since the user area is not part of the event payload, it will not be transmitted as part of a packet etc. A user area ID can further be used to identify the user area contents. The event user area ID is stored outside of the user area itself and is thus always available, even if the size of the user area data is set to zero(0). See em_pool_create(), em_event_uarea_get(), em_event_uarea_id_get/set() and em_event_uarea_info() for more information on the event user area and its associated ID.

Vector Events

Event (major) Type: EM_EVENT_TYPE_VECTOR

Vector events contain a table of events. All events in the event-table must be of major type EM_EVENT_TYPE_PACKET. Storing events of another type into the event-table is an error and leads to undefined behaviour. Event vector pools are created with em_pool_create() with the pool event-type set to EM_EVENT_TYPE_VECTOR. Event vectors can then be allocated from vector pools by calling em_alloc(..., vector_pool). To free the vector event along with all events it contains, use em_free() or em_free_multi(). To free the vector event only, not the events it contains, use em_event_vector_free().

Function Documentation

◆ em_alloc()

em_event_t em_alloc ( uint32_t  size,
em_event_type_t  type,
em_pool_t  pool 
)

Allocate an event.

Allocate a new event from the given pool. The pool used must support events of the requested (major) type:

  • Events of (major) type EM_EVENT_TYPE_SW can be allocated from pools created to support event types EM_EVENT_TYPE_SW or EM_EVENT_TYPE_PACKET.
  • Events of (major) type EM_EVENT_TYPE_PACKET can be allocated from pools created to support the event type EM_EVENT_TYPE_PACKET.
  • Event vectors of (major) type EM_EVENT_TYPE_VECTOR can be allocated from pools created to support the event type EM_EVENT_TYPE_VECTOR.

The memory address of the allocated event is system specific and can depend on the given pool, event size and type. The returned event (handle) may refer to a memory buffer, packet or vector etc., i.e. the event structure is event type specific.

Use em_event_pointer(), or for vectors em_event_vector_tbl(), to convert an event (handle) to a pointer to the event payload or access the vector table. EM does not initialize the payload data.

Concerning events and pools of type EM_EVENT_TYPE_SW or EM_EVENT_TYPE_PACKET:

  • EM_EVENT_TYPE_SW with minor type '0' is reserved for direct portability - it is always guaranteed to produce an event with contiguous payload that can directly be used by the application up to the given size (no HW specific descriptors etc. are visible). This event payload will be 64-bit aligned by default (unless explicitly configured otherwise).
  • EM_POOL_DEFAULT can be used as a pool handle if there's no need to use a specific event pool (up to the size- or event limits of that pool).

Additionally it is guaranteed, that two separate buffers never share a cache line (to avoid false sharing).

Note
Vector events must always have their major event type set to EM_EVENT_TYPE_VECTOR or EM will not recognize them as vectors. Also, the event type for periodic timer ring events, EM_EVENT_TYPE_TIMER_IND, must NOT be used with em_alloc().
Parameters
size1) Packet & sw-buf: event size in bytes (B), size > 0. 2) Vector: number of event handles that should fit into the vector table of the event, size > 0.
typeEvent type to allocate. The event major-type must be supported by given 'pool'. Vector events must be allocated with major type EM_EVENT_TYPE_VECTOR from a pool created to support vectors.
poolEvent pool handle. The pool must have been created to support events of type 'em_event_type_major(type)'
Returns
The allocated event or EM_EVENT_UNDEF on error.
See also
em_free(), em_send(), em_event_pointer(), em_receive_func_t, em_event_clone() etc.
additionally for vector events: em_event_vector_tbl(), em_event_vector_free() etc.
Examples
api_hooks.c, atomic_processing_end.c, bench_event.c, bench_pool.c, dispatcher_callback.c, error.c, event_group.c, event_group_abort.c, event_group_assign_end.c, event_group_chaining.c, fractal.c, hello.c, loop.c, loop_refs.c, loop_vectors.c, ordered.c, pairs.c, pool_perf.c, queue_group.c, queue_groups.c, queue_types_ag.c, queue_types_local.c, queues.c, queues_local.c, queues_output.c, queues_unscheduled.c, scheduling_latency.c, send_multi.c, timer_hello.c, timer_test.c, timer_test_periodic.c, and timer_test_ring.c.

Definition at line 33 of file event_machine_event.c.

◆ em_alloc_multi()

int em_alloc_multi ( em_event_t  events[],
int  num,
uint32_t  size,
em_event_type_t  type,
em_pool_t  pool 
)

Allocate multiple events.

Similar to em_alloc(), but allows allocation of multiple events, with same properties, with one function call. The em_alloc_multi() API function will try to allocate the requested number ('num') of events but may fail to do so, e.g. if the pool has run out of events, and will return the actual number of events that were successfully allocated from the given pool.

Note
Vector events must always have their major event type set to EM_EVENT_TYPE_VECTOR or EM will not recognize them as vectors. Also, the event type for periodic timer ring events, EM_EVENT_TYPE_TIMER_IND, must NOT be used with em_alloc_multi().
Parameters
[out]eventsOutput event array, events are allocated and filled by em_alloc_multi(). The given array must fit 'num' events.
numNumber of events to allocate and write into 'events[]'
size1) Packet & sw-buf: event size in bytes (B), size > 0. 2) Vector: number of event handles that should fit into the vector table of the event, size > 0.
typeEvent type to allocate. The event major-type must be supported by given 'pool'. Vector events must be allocated with major type EM_EVENT_TYPE_VECTOR from a pool created to support vectors.
poolEvent pool handle. The pool must have been created to support events of type 'em_event_type_major(type)'
Returns
Number of events actually allocated from the pool (0 ... num) and written into the output array 'events[]'.
See also
em_alloc() for more documentation.
Examples
bench_event.c, loop_multircv.c, and pool_perf.c.

Definition at line 92 of file event_machine_event.c.

◆ em_event_clone()

em_event_t em_event_clone ( em_event_t  event,
em_pool_t  pool 
)

Clone an event.

Allocate a new event with identical payload to the given event.

If present, the event user area is also cloned. Note that if a 'pool' is given and it has been configured to provide a smaller user area for events than the pool the original event was allocated from, then the clone operation will fail, returning EM_EVENT_UNDEF. Thus make sure to use compatible pools for cloning. Using the same pool ('pool' == EM_POOL_UNDEF) will always be compatible with respect of the user area sizing.

Note
Other event metadata, internal headers and state are NOT cloned (e.g. the event-group of a cloned event is EM_EVENT_GROUP_UNDEF etc).
Parameters
eventEvent to be cloned, must be a valid event.
poolOptional event pool to allocate the cloned event from. Use 'EM_POOL_UNDEF' to clone from the same pool as 'event' was allocated from. The event-type of 'event' must be suitable for allocation from 'pool' (e.g. EM_EVENT_TYPE_PACKET can not be allocated from a pool supporting only EM_EVENT_TYPE_SW) The user area size of events from 'pool' must be large enough to fit the cloned user area.
Returns
The cloned event or EM_EVENT_UNDEF on error.
See also
em_alloc(), em_free()
Examples
bench_event.c.

Definition at line 1454 of file event_machine_event.c.

◆ em_event_clone_part()

em_event_t em_event_clone_part ( em_event_t  event,
em_pool_t  pool,
uint32_t  offset,
uint32_t  len,
bool  clone_uarea 
)

Partially clone an event.

Allocate a new event (of size 'len') and copy 'len' bytes of data starting from 'offset' from the given event into the new event. The maximum number of bytes to copy is event-size minus the offset.

If present, and 'clone_uarea = true', the event user area is also cloned. Note that if a 'pool' is given and it has been configured to provide a smaller user area for events than the pool the original event was allocated from, then the clone operation will fail, returning EM_EVENT_UNDEF. Thus make sure to use compatible pools for cloning. Using the same pool ('pool' == EM_POOL_UNDEF) will always be compatible with respect of the user area sizing.

Note
Other event metadata, internal headers and state are NOT cloned (e.g. the event-group of a cloned event is EM_EVENT_GROUP_UNDEF etc).
Parameters
eventEvent to be cloned, must be a valid event.
poolOptional event pool to allocate the partially cloned event from. Use 'EM_POOL_UNDEF' to clone from the same pool as 'event' was allocated from. The event-type of 'event' must be suitable for allocation from 'pool' (e.g. EM_EVENT_TYPE_PACKET can not be allocated from a pool supporting only EM_EVENT_TYPE_SW). The user area size of events from 'pool' must be large enough to fit the cloned user area (if 'clone_uarea = true').
offsetByte offset into the event payload
lenNumber of bytes to copy/clone.
clone_uareaSet 'true' to also clone the event user area (true/false).
Returns
The partially cloned event or EM_EVENT_UNDEF on error.
See also
em_alloc(), em_free()
Examples
bench_event.c.

Definition at line 1459 of file event_machine_event.c.

◆ em_event_get_pool()

em_pool_t em_event_get_pool ( em_event_t  event)

Returns the EM event-pool the event was allocated from.

The EM event-pool for the given event can only be obtained if the event has been allocated from a pool created with em_pool_create(). For other pools, e.g. external (to EM) pktio pools, EM_POOL_UNDEF is returned.

Parameters
eventEvent handle
Returns
The EM event-pool handle or EM_POOL_UNDEF if no EM pool is found. EM_POOL_UNDEF is returned also for a valid event that has been allocated from a pool external to EM (no error is reported).
Examples
bench_event.c.

Definition at line 876 of file event_machine_event.c.

◆ em_event_get_pool_subpool()

em_pool_t em_event_get_pool_subpool ( em_event_t  event,
int *  subpool 
)

Returns the EM event-pool and subpool the event was allocated from.

Similar to em_event_get_pool(), but also outputs the subpool the event was allocated from. The subpool is in the range [0, EM_MAX_SUBPOOLS - 1].

Parameters
eventEvent handle
[out]subpoolSubpool index, output arg filled on successful return. Use 'NULL' if not interested in the subpool (or prefer em_event_get_pool() instead). The subpool is filled only when a valid EM pool can be found, i.e. when the return value is other than EM_POOL_UNDEF - EM doesn't touch it otherwise.
Returns
The EM event-pool handle or EM_POOL_UNDEF if no EM pool is found. EM_POOL_UNDEF is returned also for a valid event that has been allocated from a pool external to EM (no error is reported).
Examples
bench_event.c.

Definition at line 899 of file event_machine_event.c.

◆ em_event_get_size()

uint32_t em_event_get_size ( em_event_t  event)

Returns the event payload size in bytes (B) of the given event

Returns the event type specific payload size of the event. For events of (major) type sw buf or packet the size is the available buffer/payload size in bytes (B).

Note
Do not use this API function for vector events, instead use em_event_vector_size(), em_event_vector_max_size() or em_event_vector_info(). Use the event type to distinguish between vectors and other types of events.
Parameters
eventEvent handle
Returns
Event type specific payload size in bytes.
Examples
bench_event.c, queues.c, queues_local.c, queues_output.c, queues_unscheduled.c, and send_multi.c.

Definition at line 818 of file event_machine_event.c.

◆ em_event_get_type()

em_event_type_t em_event_get_type ( em_event_t  event)

Get the event type of an event

Returns the type of the given event. The type has been set by em_alloc...(), em_event_set_type() or e.g. packet input.

Parameters
eventEvent handle
Returns
event type, EM_EVENT_TYPE_UNDEF on error
See also
em_alloc(), em_event_set_type(), em_event_type_major(), em_event_type_minor(), em_receive_func_t(..., em_event_type_t type, ...)
Examples
bench_event.c.

Definition at line 968 of file event_machine_event.c.

◆ em_event_get_type_multi()

int em_event_get_type_multi ( const em_event_t  events[],
int  num,
em_event_type_t  types[] 
)

Get the event types of multiple events

Writes the event type of each given event into an output type-array and returns the number of entries written. Note, if 'events[num]' are all of the same type then 'types[num]' will contain 'num' same entries.

Parameters
eventsEvent handles: events[num]
numNumber of events and output types. The array 'events[]' must contain 'num' entries and the output array 'types[]' must have room for 'num' entries.
[out]typesEvent types (output array): types[num] (types[i] is the type of events[i])
Returns
Number of event types (0...num) written into 'types[]'. The return value (always >=0) is usually 'num' and thus '<num' is only seen in error scenarios when the type of event[i] could not be obtained. The return value will be '0' in error cases or if the given 'num=0'. The function stops and returns on the first error and will not fill the rest of 'types[]'.
Examples
bench_event.c.

Definition at line 989 of file event_machine_event.c.

◆ em_event_has_ref()

bool em_event_has_ref ( em_event_t  event)

Test if an event has references

An event that has multiple references share data with other events and thus the (shared) data must not be modified.

New references are created with the em_event_ref() API call. The intent of multiple references is to avoid event copies. When a reference is created, this function returns 'true' for both events (i.e. for the original event and the new reference).

Parameters
eventEvent handle
Return values
falseThis event has no references
trueThe event has multiple references
Examples
bench_event.c.

Definition at line 1734 of file event_machine_event.c.

◆ em_event_mark_free()

void em_event_mark_free ( em_event_t  event)

Mark the event as "free".

Indicates a user-given promise to EM that the event will be freed back into the pool it was allocated from e.g. by HW or device drivers (external to EM). Calling em_event_mark_free() transfers event ownership away from the user, and thus the event must not be used or touched by the user anymore.

Example use case: A user provided output-callback function associated with a queue of type 'EM_QUEUE_TYPE_OUTPUT' can use this API when configuring a HW-device or device-driver to free the event (outside of EM) after transmission.

EM will, after this API-call, treat the event as "freed" and any further API operations or usage might lead to EM errors (depending on the error-check level), e.g. em_send/free/tmo_set/ack(event) etc. is forbidden after em_event_mark_free(event).

Note
Registered API-callback hooks for em_free/_multi() (em_api_hook_free_t) will NOT be called.
Parameters
eventEvent to be marked as "free"
See also
em_free(), em_event_unmark_free()

Definition at line 1132 of file event_machine_event.c.

◆ em_event_mark_free_multi()

void em_event_mark_free_multi ( const em_event_t  events[],
int  num 
)

Mark multiple events as "free".

Similar to em_event_mark_free(), but allows the marking of multiple events as "free" with one function call.

Note
Registered API-callback hooks for em_free/_multi() (em_api_hook_free_t) will NOT be called.
Parameters
[in]eventsArray of events to be marked as "free"
numThe number of events in the array 'events[]'

Definition at line 1181 of file event_machine_event.c.

◆ em_event_mark_send()

em_status_t em_event_mark_send ( em_event_t  event,
em_queue_t  queue 
)

Mark the event as "sent".

Indicates a user-given promise to EM that the event will later appear into 'queue' by some means other than an explicit user call to em_send...(). Calling em_event_mark_send() transfers event ownership away from the user, and thus the event must not be used or touched by the user anymore (the only exception is (hw) error recovery where the "sent" state can be cancelled by using em_event_unmark_send() - dangerous!).

Example use case: A user provided output-callback function associated with a queue of type 'EM_QUEUE_TYPE_OUTPUT' can use this API when configuring a HW-device to deliver the event back into EM. The HW will eventually "send" the event and it will "somehow" again appear into EM for the user to process.

EM will, after this API-call, treat the event as "sent" and any further API operations or usage might lead to EM errors (depending on the error-check level), e.g. em_send/free/tmo_set/ack(event) etc. is forbidden after em_event_mark_send(event).

Note
Registered API-callback hooks for em_send...() (em_api_hook_send_t) will NOT be called.
Marking an event "sent" with an event group (corresponding to em_send_group()) is currently NOT supported.
Parameters
eventEvent to be marked as "sent"
queueDestination queue (must be scheduled, i.e. atomic, parallel or parallel-ordered)
Returns
EM_OK if successful
See also
em_send(), em_event_unmark_send()

Definition at line 1068 of file event_machine_event.c.

◆ em_event_pointer()

void* em_event_pointer ( em_event_t  event)

Get a pointer to the event structure/data.

Returns a pointer to the beginning of the event data or NULL in case of error. The structure/content of the event data is user and/or event type specific. It may be a directly accessible buffer of memory, contain packet headers and data or have user specified content etc. Use em_event_get_type() and em_event_type_major() to determine the type of the event.

Note
em_event_pointer() should NOT be used with events of (major) type EM_EVENT_TYPE_VECTOR or EM_EVENT_TYPE_TIMER_IND - usage with these types of events returns NULL and an error is reported. Instead, when dealing with event vectors, use em_event_vector_tbl() to get access to the vector table. Further, periodic timer-ring timeout indication events have no user accessible payload.
Parameters
eventEvent handle
Returns
Pointer to the beginning of the event data
Return values
NULLon unsupported event type or other error
See also
em_event_vector_tbl() when dealing with vector events.
Examples
api_hooks.c, atomic_processing_end.c, bench_event.c, dispatcher_callback.c, error.c, event_group.c, event_group_abort.c, event_group_assign_end.c, event_group_chaining.c, fractal.c, hello.c, ordered.c, pool_perf.c, queue_group.c, queue_groups.c, queue_types_ag.c, queue_types_local.c, queues.c, queues_local.c, queues_output.c, queues_unscheduled.c, scheduling_latency.c, send_multi.c, timer_hello.c, timer_test.c, timer_test_periodic.c, and timer_test_ring.c.

Definition at line 750 of file event_machine_event.c.

◆ em_event_pointer_and_size()

void* em_event_pointer_and_size ( em_event_t  event,
uint32_t *  size 
)

Get a pointer to the event structure/data as well as the event size.

Returns a pointer to the beginning of the event data as well as the event type specific payload size via the output arg 'size'.

This API is a combination of em_event_pointer() and em_event_get_size() since both are often needed, especially in the EO-receive function where event payload manipulation naturally takes place.

The structure/content of the event data is user and/or event type specific. It may be a directly accessible buffer of memory, contain packet headers and data or have user specified content etc. Use em_event_get_type() to determine the type of the event or rely on the 'type' argument provided to the EO-receive function (em_receive_func_t). Use em_event_type_major() to get the major part of the event type.

Note
Do not use this API function for vector events (major event type EM_EVENT_TYPE_VECTOR) or periodic timer ring timeout events (event type EM_EVENT_TYPE_TIMER_IND). Instead, for vectors use the em_event_vector_...() APIs. Timer ring timeout events have no user accessible data.
Parameters
eventEvent handle
[out]sizeOptional output arg into which the event type specific payload size (in bytes) is stored. Use 'size=NULL' if no size information is needed. Only set by the function when no errors occurred. For events of (major) type sw buf or packet the size is the available buffer/payload size in bytes (B).
Returns
Pointer to the beginning of the event data
Return values
NULLon unsupported event type or other error ('size' not touched)
See also
em_event_pointer(), em_event_get_size()
Examples
bench_event.c.

Definition at line 767 of file event_machine_event.c.

◆ em_event_ref()

em_event_t em_event_ref ( em_event_t  event)

Create a reference to an event

A reference is an additional event handle referring to an existing event. As long as an event has multiple references, none of them (including 'event') should be used to modify the event. Reading event data from a reference is allowed. Writes to the event data must only be done when there is a single event handle left, i.e. when em_event_has_ref(event) returns 'false'. Results are undefined if these restrictions are not observed.

The event is freed when the last reference, including the original event, is freed.

Currently only references to events of (major) type EM_EVENT_TYPE_PACKET can be created.

It is not allowed to use event references with event groups since assigning an event that has references to an event group would assign all the references to the event group resulting in undefined behaviour. E.g. using em_send_group()/em_send_group_multi() to send a reference is wrong.

Parameters
eventEvent handle for which a reference is to be created.
Returns
Reference to the event
Return values
EM_EVENT_UNDEFon failure
Examples
bench_event.c, and loop_refs.c.

Definition at line 1681 of file event_machine_event.c.

◆ em_event_same_type_multi()

int em_event_same_type_multi ( const em_event_t  events[],
int  num,
em_event_type_t same_type 
)

Get the number of events that have the same event type.

Returns the number of consecutive events from the start of the array 'events[]' that have the same event type. Outputs that same event type. Useful for iterating through an event-array and grouping by event type.

Parameters
eventsEvent handles: events[num]
numNumber of events. The array 'events[]' must contain 'num' entries.
[out]same_typeEvent type pointer for output
Returns
Number of consecutive events (0...num) with the same event type (return value always >=0), includes and starts from events[0]. The return value is usually '>=1' and thus '0' is only seen in error scenarios when the type of the first event could not be obtained or if the given 'num=0'. The function stops and returns on the first error.
Examples
bench_event.c.

Definition at line 1028 of file event_machine_event.c.

◆ em_event_set_type()

em_status_t em_event_set_type ( em_event_t  event,
em_event_type_t  newtype 
)

Set the event type of an event

The operation may fail if (the major part of) the new type is not compatible with the old one. EM does not check the compatibility of the new vs. old event type for all cases, thus the user must take care not to incorrectly update the type.

Note
Vector events must always have their major type set to EM_EVENT_TYPE_VECTOR or EM will not recognize them as vectors. Also, timer ring events must always have their event type set to EM_EVENT_TYPE_TIMER_IND or EM will not recognize them as periodic timer ring timeout events. Trying to set an incorrect type for these events result in error.
Parameters
eventEvent handle
newtypeNew type for the event
Returns
EM_OK on success
See also
em_alloc(), em_event_get_type/_multi(), em_event_type_major(), em_event_type_minor(), em_receive_func_t(..., em_event_type_t type, ...)
Examples
bench_event.c.

Definition at line 923 of file event_machine_event.c.

◆ em_event_to_u64()

uint64_t em_event_to_u64 ( em_event_t  event)

Convert an event handle to an unsigned integer

Parameters
eventEvent handle to be converted
Returns
uint64_t value that can be used to print/display the handle
Note
This routine is intended to be used for diagnostic purposes to enable applications to e.g. generate a printable value that represents an em_event_t handle.

Definition at line 1896 of file event_machine_event.c.

◆ em_event_uarea_get()

void* em_event_uarea_get ( em_event_t  event,
size_t *  size 
)

Get a pointer to the event user area, optionally along with its size.

The event user area is a fixed sized area located within the event metadata (i.e. outside of the event payload) that can be used to store application specific event related data without the need to adjust the payload. The event user area is configured during EM event pool creation and thus the size of the user area is set per pool.

Note that the user area content is not initialized by EM, neither em_alloc() nor em_free() will touch it and thus it might contain old user data set the last time the area was used during a previous allocation of the same event. Since the user area is not part of the event payload, it will not be transmitted as part of a packet etc.

Parameters
eventEvent handle to get the user area of
[out]sizeOptional output arg into which the user area size is stored. Use 'size=NULL' if no size information is needed.
Returns
a pointer to the event user area
Return values
NULLon error or if the event contains no user area
See also
em_pool_create() for pool specific configuration and the CLI (Command Line Interface) related runtime config file em-odp.conf for the default value: 'pool.user_area_size'.
em_event_uarea_info() if both user area ptr and ID is needed
Examples
bench_event.c, and queue_types_ag.c.

Definition at line 1531 of file event_machine_event.c.

◆ em_event_uarea_id_get()

em_status_t em_event_uarea_id_get ( em_event_t  event,
bool *  isset,
uint16_t *  id 
)

Get the event user area ID along with information if it has been set.

The event user area can be associated with an optional ID that e.g. can be used to identify the contents of the actual user area data. The ID is stored outside of the actual user area data and is available for use even if the user area size has been set to zero(0) for the pool the event was allocated from.

This function is used to determine whether the user area ID has been set earlier and to retrieve the ID in the case it has been set. EM will initialize 'ID isset = false' when allocating a new event (indicating that the ID is not set). Use em_event_uarea_id_set() to set the ID.

Parameters
eventEvent handle to get the user area ID and "set"-status of
[out]issetOptional output arg: has the ID been set previously? At least one of 'isset' and 'id' must be given (or both).
[out]idOptional output arg into which the user area ID is stored if it has been set before. The output arg 'isset' should be used to determine whether 'id' has been set. Note: 'id' will not be touched if the ID has not been set earlier (i.e. when 'isset' is 'false'). At least one of 'isset' and 'id' must be given (or both).
Returns
EM_OK if successful
See also
em_event_uarea_id_set(), em_event_uarea_get()
em_event_uarea_info() if both user area ptr and ID is needed
Examples
bench_event.c.

Definition at line 1590 of file event_machine_event.c.

◆ em_event_uarea_id_set()

em_status_t em_event_uarea_id_set ( em_event_t  event,
uint16_t  id 
)

Set the event user area ID.

The event user area can be associated with an optional ID that e.g. can be used to identify the contents of the actual user area data. The ID is stored outside of the actual user area data and is available for use even if the user area size has been set to 0 for the pool the event was allocated from.

This function is used to set the event user area ID for the given event. The 'set' operation overwrites any ID stored earlier. Use em_event_uarea_id_get() to check whether an ID has been set earlier and to retrieve the ID.

Parameters
eventEvent handle for which to set the user area ID
idThe user area ID to set
Returns
EM_OK if successful
See also
em_event_uarea_id_get(), em_event_uarea_get(), em_event_uarea_info()
Examples
bench_event.c, and queue_types_ag.c.

Definition at line 1568 of file event_machine_event.c.

◆ em_event_uarea_info()

em_status_t em_event_uarea_info ( em_event_t  event,
em_event_uarea_info_t uarea_info 
)

Get the event user area information for a given event.

Obtain information about the event user area for a certain given event. Information containing the user area pointer, size, as well as the ID is output via the 'uarea_info' struct. This API function combines the functionality of em_event_uarea_get() and em_event_uarea_id_get() for use cases where both the user area pointer as well as the ID is needed. Calling one API function instead of two might be faster due to a fewer checks and internal conversions.

The event user area is a fixed sized area located within the event metadata (i.e. outside of the event payload) that can be used to store application specific event related data without the need to adjust the payload. The event user area is configured during EM event pool creation and thus the size of the user area is set per pool.

Note that the user area content is not initialized by EM, neither em_alloc() nor em_free() will touch it and thus it might contain old user data set the last time the area was used during a previous allocation of the same event. Since the user area is not part of the event payload, it will not be transmitted as part of a packet etc.

The event user area can be associated with an optional ID that can be used to identify the contents of the actual user area data. The ID is stored outside of the actual user area data and is available for use even if the user area size has been set to zero(0) for the pool the event was allocated from. EM will initialize 'uarea_info.id.isset = false' when allocating a new event (indicating that the ID is not set).

Parameters
eventEvent handle to get the user area information of.
[out]uarea_infoOutput struct into which the user area information is stored.
Returns
EM status code incidating success or failure of the operation.
Return values
EM_OKOperation successful.
OtherOperation FAILED and no valid user area info could be obtained, 'uarea_info' is all NULL/zero(0) in this case.
See also
em_pool_create() for pool specific configuration and the CLI (Command Line Interface) related runtime config file em-odp.conf for the default value: 'pool.user_area_size'.
em_event_uarea_get(), em_event_uarea_id_get()
Examples
bench_event.c, and queue_types_ag.c.

Definition at line 1628 of file event_machine_event.c.

◆ em_event_unmark_free()

void em_event_unmark_free ( em_event_t  event)

Unmark an event previously marked as "free" (i.e mark as "allocated" again).

Note
This is for recovery situations only and can potentially crash the application if used incorrectly! Unmarking the free-state of an event that has already been freed will lead to fatal error.

Revert an event's "free" state, as set by em_event_mark_free(), back to the state before the mark-free function call. Any further usage of the event after em_event_mark_free(), by EM or the user, will result in error when calling em_event_unmark_free() since the state has become unrecoverable. => the only allowed EM API call after em_event_mark_free() (for a certain event) is em_event_unmark_free() when it is certain that the event, due to some external error, will not be freed otherwise and must be recovered back into the EM-domain so that calling em_free() by the user is possible. Calling em_event_unmark_free() transfers event ownership back to the user again.

Note
Unmark-send and unmark-free are the only valid cases of using an event that the user no longer owns - all other such uses leads to fatal error
hw_err_t hw_err;
// 'event' owned by the user
// 'event' no longer owned by the user - don't touch!
hw_err = config_hw_to_transmit_event(...hw-cfg..., event);
if (hw_err) {
// hw config error - the event can be recovered if it is
// certain that the hw won't free that same event.
// note: the user doesn't own the event here and actually
// uses an obsolete event handle to recover the event.
// 'event' recovered, again owned by the user
em_free(event);
}
Parameters
eventEvent previously marked as "free" with em_event_mark_free/_multi(), any other usecase is invalid!
See also
em_free(), em_event_mark_free()

Definition at line 1157 of file event_machine_event.c.

◆ em_event_unmark_free_multi()

void em_event_unmark_free_multi ( const em_event_t  events[],
int  num 
)

Unmark multiple events previously marked as "free".

Note
This is for recovery situations only and can potentially crash the application if used incorrectly!

Similar to em_event_unmark_free(), but allows to do the "free"-unmarking of multiple events with one function call.

Parameters
[in]eventsEvents previously marked as "free" with em_event_mark_free/_multi(), any other usecase is invalid!
numThe number of events in the array 'events[]'

Definition at line 1225 of file event_machine_event.c.

◆ em_event_unmark_send()

em_status_t em_event_unmark_send ( em_event_t  event)

Unmark an event previously marked as "sent" (i.e mark as "unsent")

Note
This is for recovery situations only and can potentially crash the application if used incorrectly!

Revert an event's "sent" state, as set by em_event_mark_send(), back to the state before the mark-send function call. Any further usage of the event after em_event_mark_send(), by EM or the user, will result in error when calling em_event_unmark_send() since the state has become unrecoverable. => the only allowed EM API call after em_event_mark_send() is em_event_unmark_send() if it is certain that the event, due to some external error, will never be sent into EM again otherwise. Calling em_event_unmark_send() transfers event ownership back to the user again.

Note
Unmark-send and unmark-free are the only valid cases of using an event that the user no longer owns - all other such uses leads to fatal error
hw_err_t hw_err;
// 'event' owned by the user
err = em_event_mark_send(event, queue);
if (err != EM_OK)
return err; // NOK
// 'event' no longer owned by the user - don't touch!
hw_err = config_hw_to_send_event(...hw-cfg..., event, queue);
if (hw_err) {
// hw config error - the event can be recovered if it is
// certain that the hw won't send that same event.
// note: the user doesn't own the event here and actually
// uses an obsolete event handle to recover the event.
err = em_event_unmark_send(event);
if (err != EM_OK)
return err; // NOK
// 'event' recovered, again owned by the user
em_free(event);
}
Parameters
eventEvent previously marked as "sent" with em_event_mark_send(), any other case will be invalid!
Returns
EM_OK if successful
See also
em_send(), em_event_mark_send()

Definition at line 1110 of file event_machine_event.c.

◆ em_event_vector_free()

void em_event_vector_free ( em_event_t  vector_event)

Free the vector event only, not the events it contains.

Frees only the vector event itself and not the events it contains in its vector-table. To free the vector event along with all events it contains, use em_free() or em_free_multi().

Parameters
vector_eventVector event handle
Examples
bench_event.c, and loop_vectors.c.

Definition at line 1746 of file event_machine_event.c.

◆ em_event_vector_info()

em_status_t em_event_vector_info ( em_event_t  vector_event,
em_event_vector_info_t vector_info 
)

Retrieve information about the given vector event.

Vector event information is output via the struct 'vector_info'. Combines the APIs em_event_vector_tbl(), em_event_vector_size() and em_event_vector_max_size() into one API call.

All events in the event-table must be of major type EM_EVENT_TYPE_PACKET. Storing events of another type into the event-table is an error and leads to undefined behaviour.

Parameters
vector_eventVector event handle to get the information of.
[out]vector_infoOutput struct into which the vector information is stored.
Returns
EM status code incidating success or failure of the operation.
Return values
EM_OKOperation successful.
OtherOperation FAILED and no valid vector info could be obtained, 'vector_info' is all NULL/zero(0) in this case.
Examples
bench_event.c.

Definition at line 1856 of file event_machine_event.c.

◆ em_event_vector_max_size()

uint32_t em_event_vector_max_size ( em_event_t  vector_event)

Maximum number of event handles that can be stored in a vector.

Returns the maximum number of events that can be stored into the event-table of the given vector event, i.e. the max-size that can be used with em_event_vector_size_set(). The max-size might be larger than the size requested during allocation and instead reflects the vector-size used when creating the EM event vector pool.

All events in the event-table must be of major type EM_EVENT_TYPE_PACKET. Storing events of another type into the event-table is an error and leads to undefined behaviour.

Parameters
vector_eventVector event handle
Returns
The maximum number of event handles that can be stored in the vector
Return values
>0on success
0on failure or if EM can't retrieve the max size (non-EM pool).
Examples
bench_event.c.

Definition at line 1834 of file event_machine_event.c.

◆ em_event_vector_size()

uint32_t em_event_vector_size ( em_event_t  vector_event)

Number of event handles available (set) in a vector.

Returns the number of available events in the vector. Note that the returned 'size' indicates how many valid events are stored in the vector's event-table. The 'size' neither indicates the alloc-size (size given to em_alloc()) nor the max-size of the event-table, use em_event_vector_max_size/info() to obtain that information.

All events in the event-table must be of major type EM_EVENT_TYPE_PACKET. Storing events of another type into the event-table is an error and leads to undefined behaviour.

Parameters
vector_eventVector event handle
Returns
The number of event handles available (set) in the vector
Note
A newly allocated vector has an empty event-table and thus the returned size is zero until updated with em_event_vector_size_set()
Examples
bench_event.c.

Definition at line 1796 of file event_machine_event.c.

◆ em_event_vector_size_set()

void em_event_vector_size_set ( em_event_t  vector_event,
uint32_t  size 
)

Set the number of event handles stored in a vector.

Update the number of event handles stored in a vector. This function shall be used to set the number of events available in the given vector when the application itself is producing (or updating) the event vector. Only valid event handles can be stored into the vector's event-table. The events must be stored into the vector before setting the size, i.e. first add/remove events to/from the vector's event-table (within max-size limits) and only after that set the size.

All events in the event-table must be of major type EM_EVENT_TYPE_PACKET. Storing events of another type into the event-table is an error and leads to undefined behaviour.

Parameters
vector_eventVector event handle
sizeNumber of event handles in the vector
Note
The maximum number of event handles the vector can hold is defined by em_pool_cfg_t::subpool[i].size or can be obtained for a specific vector with em_event_vector_max_size(vector_event).
All handles in the vector table (0 ... size - 1) need to be valid event handles.
Examples
bench_event.c, and loop_vectors.c.

Definition at line 1815 of file event_machine_event.c.

◆ em_event_vector_tbl()

uint32_t em_event_vector_tbl ( em_event_t  vector_event,
em_event_t **  event_tbl 
)

Get the event vector table from an event of (major) type EM_EVENT_TYPE_VECTOR.

The event vector table is an array of event handles (em_event_t) stored in a contiguous memory location for events with major event type set to EM_EVENT_TYPE_VECTOR. Upon completion of this API, this function returns the event table pointer of the given vector event via the output argument 'event_tbl'.

All events in the event-table must be of major type EM_EVENT_TYPE_PACKET. Storing events of another type into the event-table is an error and leads to undefined behaviour.

Parameters
vector_eventVector event handle
[out]event_tblPointer into which the event table (ptr) is written
Returns
Number of event handles available (set) in the vector event.
Note
A newly allocated vector has an empty event-table and thus the returned size is zero until updated with em_event_vector_size_set().
em_event_type_t event_type = em_event_get_type(vector_event);
if (em_event_type_major(event_type) == EM_EVENT_TYPE_VECTOR) {
em_event_t *event_tbl;
uint32_t num = em_event_vector_tbl(vector_event, &event_tbl);
if (!num)
return;
for (uint32_t i = 0; i < num; i++) {
event = event_tbl[i];
... process 'event' ...
}
}
See also
em_event_vector_size_set()
Examples
bench_event.c, and loop_vectors.c.

Definition at line 1776 of file event_machine_event.c.

◆ em_free()

void em_free ( em_event_t  event)

Free an event.

The em_free() function transfers ownership of the event back to the system and the application must not touch the event (or related memory buffers) after calling it.

It is assumed that the implementation can detect the event pool that the event was originally allocated from.

The application must only free events it owns. For example, the sender must not free an event after sending it.

Note
Freeing a vector event (of type EM_EVENT_VECTOR) with this API will also free the events contained in the vector's event-table. To free only the vector event itself, use em_event_vector_free().
Parameters
eventEvent to be freed
See also
em_alloc(), em_free_multi(), em_event_vector_free()
Examples
api_hooks.c, atomic_processing_end.c, bench_event.c, bench_pool.c, dispatcher_callback.c, error.c, event_group.c, event_group_abort.c, event_group_assign_end.c, event_group_chaining.c, fractal.c, hello.c, loop.c, loop_refs.c, loop_vectors.c, ordered.c, pairs.c, pool_perf.c, queue_group.c, queue_groups.c, queue_types_ag.c, queue_types_local.c, queues.c, queues_local.c, queues_output.c, queues_unscheduled.c, scheduling_latency.c, send_multi.c, timer_hello.c, timer_test.c, timer_test_periodic.c, and timer_test_ring.c.

Definition at line 261 of file event_machine_event.c.

◆ em_free_multi()

void em_free_multi ( em_event_t  events[],
int  num 
)

Free multiple events.

Similar to em_free(), but allows freeing of multiple events with one function call. The application must not touch the given events after a call to em_free_multi().

Note
Freeing vector events (of type EM_EVENT_VECTOR) with this API will also free the events contained in the vectors' event-table. To free only the vector event itself, use em_event_vector_free().
Parameters
[in]eventsArray of events to be freed
numThe number of events in the array 'events[]'
Examples
bench_event.c, loop_multircv.c, pool_perf.c, queues_unscheduled.c, and send_multi.c.

Definition at line 370 of file event_machine_event.c.

◆ em_send()

em_status_t em_send ( em_event_t  event,
em_queue_t  queue 
)

Send an event to a queue.

The event must have been allocated with em_alloc(), or received via an EO receive-function. The sender must not touch the event after calling em_send() as the ownership has been transferred to the system or possibly to the next receiver. If the return status is not EM_OK, the ownership has not been transferred and the application is still responsible for the event (e.g. may free it).

EM does not currently define guaranteed event delivery, i.e. EM_OK return value only means the event was accepted for delivery. It could still be lost during delivery (e.g. due to a removed queue or system congestion, etc).

Parameters
eventEvent to be sent
queueDestination queue
Returns
EM_OK if successful (accepted for delivery).
See also
em_alloc()
Examples
api_hooks.c, atomic_processing_end.c, bench_event.c, dispatcher_callback.c, error.c, event_group.c, event_group_abort.c, event_group_assign_end.c, event_group_chaining.c, fractal.c, hello.c, loop.c, loop_refs.c, loop_vectors.c, ordered.c, pairs.c, pool_perf.c, queue_group.c, queue_groups.c, queue_types_ag.c, queue_types_local.c, queues.c, queues_local.c, queues_output.c, queues_unscheduled.c, scheduling_latency.c, send_multi.c, and timer_test_periodic.c.

Definition at line 661 of file event_machine_event.c.

◆ em_send_multi()

int em_send_multi ( const em_event_t  events[],
int  num,
em_queue_t  queue 
)

Send multiple events to a queue.

As em_send, but multiple events can be sent with one call for potential performance gain. The function returns the number of events actually sent. A return value equal to the given 'num' means that all events were sent. A return value less than 'num' means that only the first 'num' events were sent and the rest must be handled by the application.

Parameters
eventsArray of events to send
numNumber of events. The array 'events[]' must contain 'num' entries.
queueDestination queue
Returns
number of events successfully sent (equal to num if all successful)
See also
em_send()
Examples
atomic_processing_end.c, bench_event.c, fractal.c, loop.c, loop_multircv.c, loop_refs.c, loop_vectors.c, ordered.c, pairs.c, queue_types_ag.c, queue_types_local.c, queues_unscheduled.c, and send_multi.c.

Definition at line 710 of file event_machine_event.c.

em_event_mark_send
em_status_t em_event_mark_send(em_event_t event, em_queue_t queue)
Definition: event_machine_event.c:1068
EM_EVENT_TYPE_VECTOR
@ EM_EVENT_TYPE_VECTOR
Definition: event_machine_hw_types.h:84
EM_OK
#define EM_OK
Definition: event_machine_types.h:329
em_free
void em_free(em_event_t event)
Definition: event_machine_event.c:261
em_event_unmark_free
void em_event_unmark_free(em_event_t event)
Unmark an event previously marked as "free" (i.e mark as "allocated" again).
Definition: event_machine_event.c:1157
em_event_get_type
em_event_type_t em_event_get_type(em_event_t event)
Definition: event_machine_event.c:968
em_status_t
uint32_t em_status_t
Definition: event_machine_types.h:321
em_event_vector_tbl
uint32_t em_event_vector_tbl(em_event_t vector_event, em_event_t **event_tbl)
Get the event vector table from an event of (major) type EM_EVENT_TYPE_VECTOR.
Definition: event_machine_event.c:1776
em_event_type_t
uint32_t em_event_type_t
Definition: event_machine_types.h:85
em_event_unmark_send
em_status_t em_event_unmark_send(em_event_t event)
Definition: event_machine_event.c:1110
em_event_mark_free
void em_event_mark_free(em_event_t event)
Mark the event as "free".
Definition: event_machine_event.c:1132