EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
event_machine_event.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015-2026, Nokia Solutions and Networks
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of the copyright holder nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef EVENT_MACHINE_EVENT_H_
32#define EVENT_MACHINE_EVENT_H_
33
34#pragma GCC visibility push(default)
35
36/**
37 * @file
38 * @defgroup em_event Events
39 * Operations on an event.
40 * @{
41 *
42 * All application processing is driven by events in the Event Machine. An event
43 * describes a piece of work or data to be processed. The structure of an event
44 * is event type specific: it may be a directly accessible buffer of memory,
45 * packet headers and data, a vector or user specified content etc.
46 *
47 * Applications use the event type to interpret the event structure. The event
48 * type consists of a major and a minor part: the major part specifies the
49 * actual type or structure of the event (sw buf, packet, vector etc.) while the
50 * minor part is user specific and can be used to distinguish between different
51 * use cases of the event.
52 *
53 * Events follow message passing semantics: an event has to be allocated using
54 * the provided API (em_alloc()) or received through queues by an EO callback
55 * function after which the event is owned by the application. Event ownership
56 * is transferred back to the system by using em_send() or em_free().
57 * An event not owned by the application must not be touched.
58 *
59 * The event handle, of type em_event_t, is not a direct pointer to the event
60 * structure, hence EM API functions must be used to get access to the contained
61 * data: for events of (major) type sw buffer or packet use em_event_pointer()
62 * while for vector events the contained array of event handles must be accessed
63 * with em_event_vector_tbl() instead. Use the (major part of the) event type to
64 * distinguish between vectors and other types of events.
65 *
66 * @defgroup em_event_ref Event References
67 * @ingroup em_event
68 * @{
69 * ### Event References
70 * Normally, each event is associated with one event handle (em_event_t) - each
71 * event allocation produces a new event (and associated payload data) that can
72 * be processed, sent or freed. When the user EO has allocated or received an
73 * event from a queue, the event payload data may be read and written as needed
74 * by the application.
75 * An exception to the above described scenario happens when using event
76 * references.
77 * An event reference is an additional event handle referring to an existing
78 * event. New references are created with the em_event_ref() API call. The
79 * intent of using multiple references is to avoid event copies.
80 * An event that has multiple references shares its data with the other
81 * reference handles and thus the (shared) data must not be modified.
82 * Reading event data from a reference is allowed. Writes to the event data must
83 * only be done when there is a single event handle left, i.e. when
84 * em_event_has_ref(event) returns 'false'. Results are undefined if these
85 * restrictions are not observed.
86 * The event is freed when the last reference, including the original event,
87 * is freed.
88 * It is not allowed to use event references with event groups since assigning
89 * an event that has references to an event group would assign all the
90 * references to the event group resulting in undefined behaviour. E.g. using
91 * em_send_group()/em_send_group_multi() to send a reference is wrong.
92 * @}
93 *
94 * @defgroup em_event_uarea Event User Area
95 * @ingroup em_event
96 * @{
97 * ### Event User Area
98 * An event may additionally contain a user area separate from the event
99 * payload. The size of the event user area is set when creating the event pool
100 * from which the event is allocated. The user area is a fixed size (per pool)
101 * data area into which event related state data can be stored without having
102 * to access and change the payload. Note that the size of the event user area
103 * can be zero(0), depending on event pool configuration.
104 * Note also that the user area content is not initialized by EM, neither
105 * em_alloc() nor em_free() will touch it and thus it might contain old user
106 * data set the last time the area was used during a previous allocation of the
107 * same event. Since the user area is not part of the event payload, it will not
108 * be transmitted as part of a packet etc.
109 * A user area ID can further be used to identify the user area contents.
110 * The event user area ID is stored outside of the user area itself and is thus
111 * always available, even if the size of the user area data is set to zero(0).
112 * See em_pool_create(), em_event_uarea(), em_event_uarea_id/set() and
113 * em_event_uarea_info() for more information on the event user area and its
114 * associated ID.
115 * @}
116 *
117 * @defgroup em_event_vectors Event Vectors
118 * @ingroup em_event
119 * @{
120 * ### Vector Events
121 * Event (major) Type: EM_EVENT_TYPE_VECTOR
122 *
123 * Vector events contain a table of events ('em_event_t event_tbl[]').
124 * EM supports two "modes" of event vectors selectable via the EM config file
125 * option 'vector.backend':
126 * 1) vector.backend = "event"
127 * Event vectors can contain events of any type. Aggregator queues bundle
128 * multiple events into a single event vector for more efficient queuing
129 * and scheduling. This mode requires newer ODP versions with support for
130 * ODP event vectors and event/queue aggregation.
131 * 2) vector.backend = "packet" (legacy mode)
132 * Event vectors contain only events of major type EM_EVENT_TYPE_PACKET.
133 * Storing events of another type into the event-table is an error and
134 * leads to undefined behaviour. This mode works on older ODP versions that
135 * don't support ODP event vectors. Event/queue aggregation is NOT
136 * supported.
137 * The vector backend mode is either-or and cannot be mixed in the same
138 * EM instance.
139 *
140 * Event vector pools are created with em_pool_create() with the pool event-type
141 * set to EM_EVENT_TYPE_VECTOR. Event vectors can then be allocated from vector
142 * pools by calling em_alloc(..., vector_pool).
143 * To free the vector event along with all events it contains, use em_free() or
144 * em_free_multi().
145 * To free the vector event only, not the events it contains,
146 * use em_event_vector_free().
147 *
148 * A newly allocated vector event has an empty event-table (size = 0).
149 * The application must fill the event-table via em_event_vector_tbl()
150 * and then set the vector size with em_event_vector_size_set() before
151 * sending or otherwise using the vector.
152 *
153 * The following general event APIs are NOT supported for vector events:
154 * - em_event_pointer() / em_event_pointer_and_size() - use
155 * em_event_vector_tbl() instead
156 * - em_event_size() - use em_event_vector_size() instead
157 * - em_event_clone() / em_event_clone_part()
158 * - em_event_ref()
159 *
160 * Vector events support user areas if the vector pool was configured
161 * with a non-zero user area size (see em_pool_create()).
162 * @}
163 *
164 * ### Non-EM Events
165 * Event (major) Type: EM_EVENT_TYPE_ODP
166 *
167 * EM can pass through and offer limited functionality to ODP events of types
168 * that are not natively supported by EM. These non-EM events originate from
169 * event pools that are not created by EM. Non-EM events don't have an EM event
170 * header and therefore, e.g., ESV is not used with them. These events can be
171 * sent to EM queues, dequeued from unscheduled EM queues and freed.
172 * The EM event type of a non-EM event is reported as 'EM_EVENT_TYPE_ODP'.
173 * To use a non-EM event with ODP functions, the event must first be converted
174 * to an ODP event with em_odp_event2odp() (or em_odp_events2odp()).
175 * Non-EM events received by a user EO-receive function can be handled by
176 * inspecting the event type given as a receive function argument and comparing
177 * it to 'EM_EVENT_TYPE_ODP', converting it to an ODP event and then processing
178 * it via ODP APIs.
179 */
180
183
184#ifdef __cplusplus
185extern "C" {
186#endif
187
188/**
189 * Major event types used by em_event_type_t
190 */
192 /** Undef event type */
194
195 /** SW event */
197
198 /** Packet event */
200
201 /** Timer event */
203
204 /** Crypto event */
206
207 /** Event is a vector, contains an event table */
209
210 /**
211 * Ring timer: read-only, no-payload periodic timeout indication.
212 * Only the ring timer should set this type, the user must never set
213 * this type manually via em_alloc...() or em_event_set_type().
214 */
216
217 /** Non EM event type with limited functionality compared to EM event types */
219
220 /** Any event type (used e.g. for event vector table content) */
221 EM_EVENT_TYPE_ANY = 8 << 24 /* keep last */
223
224/**
225 * @enum em_event_type_sw_minor_e
226 *
227 * Minor event types for the major EM_EVENT_TYPE_SW type.
228 */
230 EM_EVENT_TYPE_SW_DEFAULT = 0
232
233/**
234 * Allocate an event.
235 *
236 * Allocate a new event from the given pool. The pool used must support events
237 * of the requested (major) type:
238 * - Events of (major) type EM_EVENT_TYPE_SW can be allocated from pools
239 * created to support event types EM_EVENT_TYPE_SW or EM_EVENT_TYPE_PACKET.
240 * - Events of (major) type EM_EVENT_TYPE_PACKET can be allocated from pools
241 * created to support the event type EM_EVENT_TYPE_PACKET.
242 * - Event vectors of (major) type EM_EVENT_TYPE_VECTOR can be allocated from
243 * pools created to support the event type EM_EVENT_TYPE_VECTOR.
244 *
245 * The memory address of the allocated event is system specific and can depend
246 * on the given pool, event size and type. The returned event (handle) may refer
247 * to a memory buffer, packet or vector etc., i.e. the event structure is event
248 * type specific.
249 *
250 * Use em_event_pointer(), or for vectors em_event_vector_tbl(), to convert an
251 * event (handle) to a pointer to the event payload or access the vector table.
252 * EM does not initialize the payload data.
253 *
254 * Concerning events and pools of type EM_EVENT_TYPE_SW or EM_EVENT_TYPE_PACKET:
255 * - EM_EVENT_TYPE_SW with minor type '0' is reserved for direct portability -
256 * it is always guaranteed to produce an event with contiguous payload that can
257 * directly be used by the application up to the given size (no HW specific
258 * descriptors etc. are visible). This event payload will be 64-bit aligned
259 * by default (unless explicitly configured otherwise).
260 * - EM_POOL_DEFAULT can be used as a pool handle if there's no need to use a
261 * specific event pool (up to the size- or event limits of that pool).
262 *
263 * Additionally it is guaranteed, that two separate buffers never share a cache
264 * line (to avoid false sharing).
265 *
266 * @note Vector events must always have their major event type set to
267 * EM_EVENT_TYPE_VECTOR or EM will not recognize them as vectors.
268 * Also, the event type for periodic timer ring events,
269 * EM_EVENT_TYPE_TIMER_IND, must NOT be used with em_alloc().
270 *
271 * @param size 1) Packet & sw-buf: event size in bytes (B), size > 0.
272 * 2) Vector: number of event handles that should fit into
273 * the vector table of the event, size > 0.
274 * @param type Event type to allocate. The event major-type must be
275 * supported by given 'pool'. Vector events must be
276 * allocated with major type EM_EVENT_TYPE_VECTOR from a
277 * pool created to support vectors.
278 * @param pool Event pool handle. The pool must have been created to
279 * support events of type 'em_event_type_major(type)'
280 *
281 * @return The allocated event or EM_EVENT_UNDEF on error.
282 *
283 * @see em_free(), em_send(), em_event_pointer(), em_receive_func_t,
284 * em_event_clone() etc.
285 * @see additionally for vector events: em_event_vector_tbl(),
286 * em_event_vector_free() etc.
287 */
288em_event_t em_alloc(uint32_t size, em_event_type_t type, em_pool_t pool);
289
290/**
291 * Allocate multiple events.
292 *
293 * Similar to em_alloc(), but allows allocation of multiple events, with same
294 * properties, with one function call.
295 * The em_alloc_multi() API function will try to allocate the requested number
296 * ('num') of events but may fail to do so, e.g. if the pool has run out of
297 * events, and will return the actual number of events that were successfully
298 * allocated from the given pool.
299 *
300 * @note Vector events must always have their major event type set to
301 * EM_EVENT_TYPE_VECTOR or EM will not recognize them as vectors.
302 * Also, the event type for periodic timer ring events,
303 * EM_EVENT_TYPE_TIMER_IND, must NOT be used with em_alloc_multi().
304 *
305 * @param[out] events Output event array, events are allocated and filled by
306 * em_alloc_multi(). The given array must fit 'num' events.
307 * @param num Number of events to allocate and write into 'events[]'
308 * @param size 1) Packet & sw-buf: event size in bytes (B), size > 0.
309 * 2) Vector: number of event handles that should fit into
310 * the vector table of the event, size > 0.
311 * @param type Event type to allocate. The event major-type must be
312 * supported by given 'pool'. Vector events must be
313 * allocated with major type EM_EVENT_TYPE_VECTOR from a
314 * pool created to support vectors.
315 * @param pool Event pool handle. The pool must have been created to
316 * support events of type 'em_event_type_major(type)'
317 *
318 * @return Number of events actually allocated from the pool (0 ... num) and
319 * written into the output array 'events[]'.
320 *
321 * @see em_alloc() for more documentation.
322 */
323int em_alloc_multi(em_event_t events[/*out*/], int num,
324 uint32_t size, em_event_type_t type, em_pool_t pool);
325
326/**
327 * Free an event.
328 *
329 * The em_free() function transfers ownership of the event back to the system
330 * and the application must not touch the event (or related memory buffers)
331 * after calling it.
332 *
333 * It is assumed that the implementation can detect the event pool that
334 * the event was originally allocated from.
335 *
336 * The application must only free events it owns. For example, the sender must
337 * not free an event after sending it.
338 *
339 * @note Freeing a vector event (of type EM_EVENT_VECTOR) with this API will
340 * also free the events contained in the vector's event-table.
341 * To free only the vector event itself, use em_event_vector_free().
342 *
343 * @param event Event to be freed
344 *
345 * @see em_alloc(), em_free_multi(), em_event_vector_free()
346 */
347void em_free(em_event_t event);
348
349/**
350 * Free multiple events.
351 *
352 * Similar to em_free(), but allows freeing of multiple events with one
353 * function call. The application must not touch the given events after a call
354 * to em_free_multi().
355 *
356 * @note Freeing vector events (of type EM_EVENT_VECTOR) with this API will
357 * also free the events contained in the vectors' event-table.
358 * To free only the vector event itself, use em_event_vector_free().
359 *
360 * @param[in] events Array of events to be freed
361 * @param num The number of events in the array 'events[]'
362 */
363void em_free_multi(em_event_t events[], int num);
364
365/**
366 * Send an event to a queue.
367 *
368 * The event must have been allocated with em_alloc(), or received via an EO
369 * receive-function. The sender must not touch the event after calling em_send()
370 * as the ownership has been transferred to the system or possibly to the next
371 * receiver. If the return status is *not* EM_OK, the ownership has not been
372 * transferred and the application is still responsible for the event (e.g. may
373 * free it).
374 *
375 * EM does not currently define guaranteed event delivery, i.e. EM_OK return
376 * value only means the event was accepted for delivery. It could still be lost
377 * during delivery (e.g. due to a removed queue or system congestion, etc).
378 *
379 * @param event Event to be sent
380 * @param queue Destination queue
381 *
382 * @return EM_OK if successful (accepted for delivery).
383 *
384 * @see em_alloc()
385 */
386em_status_t em_send(em_event_t event, em_queue_t queue);
387
388/**
389 * Send multiple events to a queue.
390 *
391 * As em_send, but multiple events can be sent with one call for potential
392 * performance gain.
393 * The function returns the number of events actually sent. A return value equal
394 * to the given 'num' means that all events were sent. A return value less than
395 * 'num' means that only the first 'num' events were sent and the rest must be
396 * handled by the application.
397 *
398 * @param events Array of events to send
399 * @param num Number of events.
400 * The array 'events[]' must contain 'num' entries.
401 * @param queue Destination queue
402 *
403 * @return number of events successfully sent (equal to num if all successful)
404 *
405 * @see em_send()
406 */
407int em_send_multi(const em_event_t events[], int num, em_queue_t queue);
408
409/**
410 * Get a pointer to the event structure/data.
411 *
412 * Returns a pointer to the beginning of the event data or NULL in case of error.
413 * The structure/content of the event data is user and/or event type specific.
414 * It may be a directly accessible buffer of memory, contain packet headers and
415 * data or have user specified content etc.
416 * Use em_event_type() and em_event_type_major() to determine the type
417 * of the event.
418 *
419 * @note em_event_pointer() should NOT be used with events of (major) type
420 * EM_EVENT_TYPE_VECTOR or EM_EVENT_TYPE_TIMER_IND - usage with these
421 * types of events returns NULL and an error is reported.
422 * Instead, when dealing with event vectors, use em_event_vector_tbl() to
423 * get access to the vector table.
424 * Further, periodic timer-ring timeout indication events have no user
425 * accessible payload.
426 *
427 * @param event Event handle
428 *
429 * @return Pointer to the beginning of the event data
430 * @retval NULL on unsupported event type or other error
431 *
432 * @see em_event_vector_tbl() when dealing with vector events.
433 */
434void *em_event_pointer(em_event_t event);
435
436/**
437 * @brief Get a pointer to the event structure/data as well as the event size.
438 *
439 * Returns a pointer to the beginning of the event data as well as the event
440 * type specific payload size via the output arg 'size'.
441 *
442 * This API is a combination of em_event_pointer() and em_event_size() since
443 * both are often needed, especially in the EO-receive function where event
444 * payload manipulation naturally takes place.
445 *
446 * The structure/content of the event data is user and/or event type specific.
447 * It may be a directly accessible buffer of memory, contain packet headers and
448 * data or have user specified content etc.
449 * Use em_event_type() to determine the type of the event or rely on the
450 * 'type' argument provided to the EO-receive function (em_receive_func_t).
451 * Use em_event_type_major() to get the major part of the event type.
452 *
453 * @note Do not use this API function for vector events (major event type
454 * EM_EVENT_TYPE_VECTOR) or periodic timer ring timeout events
455 * (event type EM_EVENT_TYPE_TIMER_IND).
456 * Instead, for vectors use the em_event_vector_...() APIs.
457 * Timer ring timeout events have no user accessible data.
458 *
459 * @param event Event handle
460 * @param[out] size Optional output arg into which the event type specific
461 * payload size (in bytes) is stored. Use 'size=NULL' if no
462 * size information is needed. Only set by the function when
463 * no errors occurred. For events of (major) type sw buf or
464 * packet the size is the available buffer/payload size in
465 * bytes (B).
466 *
467 * @return Pointer to the beginning of the event data
468 * @retval NULL on unsupported event type or other error ('size' not touched)
469 *
470 * @see em_event_pointer(), em_event_size()
471 */
472void *em_event_pointer_and_size(em_event_t event, uint32_t *size /*out*/);
473
474/**
475 * Returns the event payload size in bytes (B) of the given event
476 *
477 * Returns the event type specific payload size of the event. For events of
478 * (major) type sw buf or packet the size is the available buffer/payload size
479 * in bytes (B).
480 *
481 * @note Do not use this API function for vector events, instead use
482 * em_event_vector_size(), em_event_vector_max_size() or
483 * em_event_vector_info(). Use the event type to distinguish between
484 * vectors and other types of events.
485 *
486 * @param event Event handle
487 *
488 * @return Event type specific payload size in bytes.
489 */
490uint32_t em_event_size(em_event_t event);
491
492/* Backwards compatible naming ("get") */
493#define em_event_get_size em_event_size
494
495/**
496 * @brief Returns the EM event-pool the event was allocated from.
497 *
498 * The EM event-pool for the given event can only be obtained if the event has
499 * been allocated from a pool created with em_pool_create(). For other pools,
500 * e.g. external (to EM) pktio pools, EM_POOL_UNDEF is returned.
501 *
502 * @param event Event handle
503 *
504 * @return The EM event-pool handle or EM_POOL_UNDEF if no EM pool is found.
505 * EM_POOL_UNDEF is returned also for a valid event that has been
506 * allocated from a pool external to EM (no error is reported).
507 */
508em_pool_t em_event_pool(em_event_t event);
509
510/* Backwards compatible naming ("get") */
511#define em_event_get_pool em_event_pool
512
513/**
514 * @brief Returns the EM event-pool and subpool the event was allocated from.
515 *
516 * Similar to em_event_pool(), but also outputs the subpool the event was
517 * allocated from.
518 * The subpool is in the range [0, EM_MAX_SUBPOOLS - 1].
519 *
520 * @param event Event handle
521 * @param[out] subpool Subpool index, output arg filled on successful return.
522 * Use 'NULL' if not interested in the subpool (or prefer
523 * em_event_pool() instead).
524 * The subpool is filled only when a valid EM pool can be
525 * found, i.e. when the return value is other than
526 * EM_POOL_UNDEF - EM doesn't touch it otherwise.
527 *
528 * @return The EM event-pool handle or EM_POOL_UNDEF if no EM pool is found.
529 * EM_POOL_UNDEF is returned also for a valid event that has been
530 * allocated from a pool external to EM (no error is reported).
531 */
532em_pool_t em_event_pool_subpool(em_event_t event, int *subpool /*out*/);
533
534/* Backwards compatible naming ("get") */
535#define em_event_get_pool_subpool em_event_pool_subpool
536
537/**
538 * Set the event type of an event
539 *
540 * The operation may fail if (the major part of) the new type is not compatible
541 * with the old one.
542 * EM does not check the compatibility of the new vs. old event type for all
543 * cases, thus the user must take care not to incorrectly update the type.
544 *
545 * @note Vector events must always have their major type set to
546 * EM_EVENT_TYPE_VECTOR or EM will not recognize them as vectors.
547 * Also, timer ring events must always have their event type set to
548 * EM_EVENT_TYPE_TIMER_IND or EM will not recognize them as periodic
549 * timer ring timeout events.
550 * Trying to set an incorrect type for these events result in error.
551 *
552 * @param event Event handle
553 * @param newtype New type for the event
554 *
555 * @return EM_OK on success
556 *
557 * @see em_alloc(), em_event_type/_multi(),
558 * em_event_type_major(), em_event_type_minor(),
559 * em_receive_func_t(..., em_event_type_t type, ...)
560 */
561em_status_t em_event_set_type(em_event_t event, em_event_type_t newtype);
562
563/**
564 * Get the event type of an event
565 *
566 * Returns the type of the given event. The type has been set by em_alloc...(),
567 * em_event_set_type() or e.g. packet input.
568 *
569 * Note that the event type consists of a major and a minor part. The major part
570 * specifies the actual type or structure of the event (sw buf, packet, vector
571 * etc.) while the minor part is user specific and can be used to distinguish
572 * between different use cases of the event.
573 * Use em_event_type_major() and em_event_type_minor() to get the major and
574 * minor parts of the event type.
575 *
576 * @param event Event handle
577 *
578 * @return event type
579 * @retval EM_EVENT_TYPE_UNDEF on error
580 *
581 * @see em_alloc(), em_event_set_type(),
582 * em_event_type_major(), em_event_type_minor(),
583 * em_receive_func_t(..., em_event_type_t type, ...)
584 */
585em_event_type_t em_event_type(em_event_t event);
586
587/* Backwards compatible naming ("get") */
588#define em_event_get_type em_event_type
589
590/**
591 * Get the major event type.
592 *
593 * The event type includes a major and a minor part. This function returns the
594 * major part. It can be compared against the enumeration em_event_type_major_e.
595 *
596 * @param type Event type
597 *
598 * @return Major event type
599 */
600static inline em_event_type_t
601em_event_type_major(em_event_type_t type)
602{
603 return type & 0xFF000000;
604}
605
606/* Backwards compatible naming */
607#define em_get_type_major em_event_type_major
608
609/**
610 * Get the minor event type.
611 *
612 * The event type includes a major and a minor part. This function returns the
613 * minor part. It can be compared against a type-specific minor enumeration.
614 *
615 * EM_EVENT_TYPE_SW_DEFAULT is reserved for (SW) events that are
616 * generic and directly accessible buffers of memory.
617 *
618 * @param type Event type
619 *
620 * @return Minor event type
621 */
622static inline em_event_type_t
623em_event_type_minor(em_event_type_t type)
624{
625 return type & 0x00FFFFFF;
626}
627
628/* Backwards compatible naming */
629#define em_get_type_minor em_event_type_minor
630
631/**
632 * Get the event types of multiple events
633 *
634 * Writes the event type of each given event into an output type-array and
635 * returns the number of entries written.
636 * Note, if 'events[num]' are all of the same type then 'types[num]' will
637 * contain 'num' same entries.
638 *
639 * @param events Event handles: events[num]
640 * @param num Number of events and output types.
641 * The array 'events[]' must contain 'num' entries and the
642 * output array 'types[]' must have room for 'num' entries.
643 * @param[out] types Event types (output array): types[num]
644 * (types[i] is the type of events[i])
645 *
646 * @return Number of event types (0...num) written into 'types[]'.
647 * The return value (always >=0) is usually 'num' and thus '<num' is
648 * only seen in error scenarios when the type of event[i] could not be
649 * obtained. The return value will be '0' in error cases or if the given
650 * 'num=0'. The function stops and returns on the first error and will
651 * not fill the rest of 'types[]'.
652 */
653int em_event_type_multi(const em_event_t events[], int num,
654 em_event_type_t types[/*out:num*/]);
655
656/* Backwards compatible naming ("get") */
657#define em_event_get_type_multi em_event_type_multi
658
659/**
660 * Get the number of events that have the same event type.
661 *
662 * Returns the number of consecutive events from the start of the array
663 * 'events[]' that have the same event type. Outputs that same event type.
664 * Useful for iterating through an event-array and grouping by event type.
665 *
666 * @param events Event handles: events[num]
667 * @param num Number of events.
668 * The array 'events[]' must contain 'num' entries.
669 * @param[out] same_type Event type pointer for output
670 *
671 * @return Number of consecutive events (0...num) with the same event type
672 * (return value always >=0), includes and starts from events[0].
673 * The return value is usually '>=1' and thus '0' is only seen in
674 * error scenarios when the type of the first event could not be
675 * obtained or if the given 'num=0'.
676 * The function stops and returns on the first error.
677 */
678int em_event_same_type_multi(const em_event_t events[], int num,
679 em_event_type_t *same_type /*out*/);
680
681/**
682 * Mark the event as "sent".
683 *
684 * Indicates a user-given promise to EM that the event will later appear into
685 * 'queue' by some means other than an explicit user call to em_send...().
686 * Calling em_event_mark_send() transfers event ownership away from the user,
687 * and thus the event must not be used or touched by the user anymore (the only
688 * exception is (hw) error recovery where the "sent" state can be cancelled by
689 * using em_event_unmark_send() - dangerous!).
690 *
691 * Example use case:
692 * A user provided output-callback function associated with a queue of type
693 * 'EM_QUEUE_TYPE_OUTPUT' can use this API when configuring a HW-device to
694 * deliver the event back into EM. The HW will eventually "send" the event and
695 * it will "somehow" again appear into EM for the user to process.
696 *
697 * EM will, after this API-call, treat the event as "sent" and any further API
698 * operations or usage might lead to EM errors (depending on the error-check
699 * level), e.g. em_send/free/tmo_set/ack(event) etc. is forbidden after
700 * em_event_mark_send(event).
701 *
702 * @note Registered API-callback hooks for em_send...() (em_api_hook_send_t)
703 * will NOT be called.
704 * @note Marking an event "sent" with an event group (corresponding to
705 * em_send_group()) is currently NOT supported.
706 *
707 * @param event Event to be marked as "sent"
708 * @param queue Destination queue (must be scheduled, i.e. atomic,
709 * parallel or ordered)
710 *
711 * @return EM_OK if successful
712 *
713 * @see em_send(), em_event_unmark_send()
714 */
715em_status_t em_event_mark_send(em_event_t event, em_queue_t queue);
716
717/**
718 * Unmark an event previously marked as "sent" (i.e mark as "unsent")
719 *
720 * @note This is for recovery situations only and can potentially crash the
721 * application if used incorrectly!
722 *
723 * Revert an event's "sent" state, as set by em_event_mark_send(), back to the
724 * state before the mark-send function call.
725 * Any further usage of the event after em_event_mark_send(), by EM or
726 * the user, will result in error when calling em_event_unmark_send() since the
727 * state has become unrecoverable.
728 * => the only allowed EM API call after em_event_mark_send() is
729 * em_event_unmark_send() if it is certain that the event, due to some
730 * external error, will never be sent into EM again otherwise.
731 * Calling em_event_unmark_send() transfers event ownership back to the user
732 * again.
733 *
734 * @note Unmark-send and unmark-free are the only valid cases of using an event
735 * that the user no longer owns - all other such uses leads to fatal error
736 *
737 * @code
738 * em_status_t err;
739 * hw_err_t hw_err;
740 *
741 * // 'event' owned by the user
742 * err = em_event_mark_send(event, queue);
743 * if (err != EM_OK)
744 * return err; // NOK
745 * // 'event' no longer owned by the user - don't touch!
746 *
747 * hw_err = config_hw_to_send_event(...hw-cfg..., event, queue);
748 * if (hw_err) {
749 * // hw config error - the event can be recovered if it is
750 * // certain that the hw won't send that same event.
751 * // note: the user doesn't own the event here and actually
752 * // uses an obsolete event handle to recover the event.
753 * err = em_event_unmark_send(event);
754 * if (err != EM_OK)
755 * return err; // NOK
756 * // 'event' recovered, again owned by the user
757 * em_free(event);
758 * }
759 * @endcode
760 *
761 * @param event Event previously marked as "sent" with em_event_mark_send(),
762 * any other case will be invalid!
763 *
764 * @return EM_OK if successful
765 *
766 * @see em_send(), em_event_mark_send()
767 */
768em_status_t em_event_unmark_send(em_event_t event);
769
770/**
771 * @brief Mark the event as "free".
772 *
773 * Indicates a user-given promise to EM that the event will be freed back into
774 * the pool it was allocated from e.g. by HW or device drivers (external to EM).
775 * Calling em_event_mark_free() transfers event ownership away from the user,
776 * and thus the event must not be used or touched by the user anymore.
777 *
778 * Example use case:
779 * A user provided output-callback function associated with a queue of type
780 * 'EM_QUEUE_TYPE_OUTPUT' can use this API when configuring a HW-device or
781 * device-driver to free the event (outside of EM) after transmission.
782 *
783 * EM will, after this API-call, treat the event as "freed" and any further API
784 * operations or usage might lead to EM errors (depending on the error-check
785 * level), e.g. em_send/free/tmo_set/ack(event) etc. is forbidden after
786 * em_event_mark_free(event).
787 *
788 * @note Registered API-callback hooks for em_free/_multi() (em_api_hook_free_t)
789 * will NOT be called.
790 *
791 * @param event Event to be marked as "free"
792 *
793 * @see em_free(), em_event_unmark_free()
794 */
795void em_event_mark_free(em_event_t event);
796
797/**
798 * @brief Unmark an event previously marked as "free"
799 * (i.e mark as "allocated" again).
800 *
801 * @note This is for recovery situations only and can potentially crash the
802 * application if used incorrectly! Unmarking the free-state of an event
803 * that has already been freed will lead to fatal error.
804 *
805 * Revert an event's "free" state, as set by em_event_mark_free(), back to the
806 * state before the mark-free function call.
807 * Any further usage of the event after em_event_mark_free(), by EM or the user,
808 * will result in error when calling em_event_unmark_free() since the state has
809 * become unrecoverable.
810 * => the only allowed EM API call after em_event_mark_free() (for a certain
811 * event) is em_event_unmark_free() when it is certain that the event, due to
812 * some external error, will not be freed otherwise and must be recovered
813 * back into the EM-domain so that calling em_free() by the user is possible.
814 * Calling em_event_unmark_free() transfers event ownership back to the user
815 * again.
816 *
817 * @note Unmark-send and unmark-free are the only valid cases of using an event
818 * that the user no longer owns - all other such uses leads to fatal error
819 *
820 * @code
821 * em_status_t err;
822 * hw_err_t hw_err;
823 *
824 * // 'event' owned by the user
825 * em_event_mark_free(event);
826 * // 'event' no longer owned by the user - don't touch!
827 *
828 * hw_err = config_hw_to_transmit_event(...hw-cfg..., event);
829 * if (hw_err) {
830 * // hw config error - the event can be recovered if it is
831 * // certain that the hw won't free that same event.
832 * // note: the user doesn't own the event here and actually
833 * // uses an obsolete event handle to recover the event.
834 * em_event_unmark_free(event);
835 * // 'event' recovered, again owned by the user
836 * em_free(event);
837 * }
838 * @endcode
839 *
840 * @param event Event previously marked as "free" with
841 * em_event_mark_free/_multi(), any other use case is invalid!
842 *
843 * @see em_free(), em_event_mark_free()
844 */
845void em_event_unmark_free(em_event_t event);
846
847/**
848 * @brief Mark multiple events as "free".
849 *
850 * Similar to em_event_mark_free(), but allows the marking of multiple events
851 * as "free" with one function call.
852 *
853 * @note Registered API-callback hooks for em_free/_multi() (em_api_hook_free_t)
854 * will NOT be called.
855 *
856 * @param[in] events Array of events to be marked as "free"
857 * @param num The number of events in the array 'events[]'
858 */
859void em_event_mark_free_multi(const em_event_t events[], int num);
860
861/**
862 * @brief Unmark multiple events previously marked as "free".
863 *
864 * @note This is for recovery situations only and can potentially crash the
865 * application if used incorrectly!
866 *
867 * Similar to em_event_unmark_free(), but allows to do the "free"-unmarking of
868 * multiple events with one function call.
869 *
870 * @param[in] events Events previously marked as "free" with
871 * em_event_mark_free/_multi(), other use cases are invalid!
872 * @param num The number of events in the array 'events[]'
873 */
874void em_event_unmark_free_multi(const em_event_t events[], int num);
875
876/**
877 * @brief Clone an event.
878 *
879 * Allocate a new event with identical payload to the given event.
880 * The major type of the event to be cloned must be EM_EVENT_TYPE_SW or
881 * EM_EVENT_TYPE_PACKET, e.g. cloning a vector event is not supported.
882 *
883 * If present, the event user area is also cloned. Note that if a 'pool' is
884 * given and it has been configured to provide a smaller user area for events
885 * than the pool the original event was allocated from, then the clone operation
886 * will fail, returning EM_EVENT_UNDEF. Thus make sure to use compatible pools
887 * for cloning. Using the same pool ('pool' == EM_POOL_UNDEF) will always be
888 * compatible with respect of the user area sizing.
889 *
890 * @note Other event metadata, internal headers and state are _NOT_ cloned
891 * (e.g. the event-group of a cloned event is EM_EVENT_GROUP_UNDEF etc).
892 *
893 * @param event Event to be cloned, must be a valid event.
894 * @param pool Optional event pool to allocate the cloned event from.
895 * Use 'EM_POOL_UNDEF' to clone from the same pool as 'event'
896 * was allocated from.
897 * The event-type of 'event' must be suitable for allocation
898 * from 'pool' (e.g. EM_EVENT_TYPE_PACKET can not be
899 * allocated from a pool supporting only EM_EVENT_TYPE_SW)
900 * The user area size of events from 'pool' must be large
901 * enough to fit the cloned user area.
902 *
903 * @return The cloned event handle
904 * @retval EM_EVENT_UNDEF on error
905 *
906 * @see em_alloc(), em_free()
907 */
908em_event_t em_event_clone(em_event_t event, em_pool_t pool/*or EM_POOL_UNDEF*/);
909
910/**
911 * @brief Partially clone an event
912 *
913 * Allocate a new event (of size 'len') and copy 'len' bytes of data starting
914 * from 'offset' from the given event into the new event.
915 * The maximum number of bytes to copy is event-size minus the offset.
916 * The major type of the event to be (partially) cloned must be EM_EVENT_TYPE_SW
917 * or EM_EVENT_TYPE_PACKET, e.g. cloning a vector event is not supported.
918 *
919 * If present, and 'clone_uarea = true', the event user area is also cloned.
920 * Note that if a 'pool' is given and it has been configured to provide a
921 * smaller user area for events than the pool the original event was allocated
922 * from, then the clone operation will fail, returning EM_EVENT_UNDEF.
923 * Thus make sure to use compatible pools for cloning.
924 * Using the same pool ('pool' == EM_POOL_UNDEF) will always be compatible with
925 * respect of the user area sizing.
926 *
927 * @note Other event metadata, internal headers and state are _NOT_ cloned
928 * (e.g. the event-group of a cloned event is EM_EVENT_GROUP_UNDEF etc).
929 *
930 * @param event Event to be cloned, must be a valid event.
931 * @param pool Optional event pool to allocate the partially cloned event from.
932 * Use 'EM_POOL_UNDEF' to clone from the same pool as 'event'
933 * was allocated from.
934 * The event-type of 'event' must be suitable for allocation
935 * from 'pool' (e.g. EM_EVENT_TYPE_PACKET can not be
936 * allocated from a pool supporting only EM_EVENT_TYPE_SW).
937 * The user area size of events from 'pool' must be large
938 * enough to fit the cloned user area (if 'clone_uarea = true').
939 * @param offset Byte offset into the event payload
940 * @param len Number of bytes to copy/clone.
941 * @param clone_uarea Set 'true' to also clone the event user area (true/false).
942 *
943 * @return The partially cloned event or EM_EVENT_UNDEF on error.
944 *
945 * @see em_alloc(), em_free()
946 */
947em_event_t em_event_clone_part(em_event_t event, em_pool_t pool/*or EM_POOL_UNDEF*/,
948 uint32_t offset, uint32_t len, bool clone_uarea);
949
950/**
951 * @addtogroup em_event_uarea
952 * @{
953 */
954
955/**
956 * @brief Get a pointer to the event user area, optionally along with its size.
957 *
958 * The event user area is a fixed sized area located within the event metadata
959 * (i.e. outside of the event payload) that can be used to store application
960 * specific event related data without the need to adjust the payload.
961 * The event user area is configured during EM event pool creation and thus the
962 * size of the user area is set per pool.
963 *
964 * Note that the user area content is not initialized by EM, neither em_alloc()
965 * nor em_free() will touch it and thus it might contain old user data set the
966 * last time the area was used during a previous allocation of the same event.
967 * Since the user area is not part of the event payload, it will not be
968 * transmitted as part of a packet etc.
969 *
970 * @param event Event handle to get the user area of
971 * @param[out] size Optional output arg into which the user area size is
972 * stored. Use 'size=NULL' if no size information is needed.
973 *
974 * @return a pointer to the event user area
975 * @retval NULL on error or if the event contains no user area
976 *
977 * @see em_pool_create() for pool specific configuration and
978 * the EM runtime config file em-odp.conf for the default value:
979 * 'pool.user_area_size'.
980 * @see em_event_uarea_info() if both user area ptr and ID is needed
981 */
982void *em_event_uarea(em_event_t event, size_t *size/*out*/);
983
984/* Backwards compatible naming ("get") */
985#define em_event_uarea_get em_event_uarea
986
987/**
988 * @brief Get the event user area ID along with information if it has been set
989 *
990 * The event user area can be associated with an optional ID that e.g. can be
991 * used to identify the contents of the actual user area data. The ID is stored
992 * outside of the actual user area data and is available for use even if the
993 * user area size has been set to zero(0) for the pool the event was allocated
994 * from.
995 *
996 * This function is used to determine whether the user area ID has been set
997 * earlier and to retrieve the ID in the case it has been set.
998 * EM will initialize 'ID isset = false' when allocating a new event (indicating
999 * that the ID is not set). Use em_event_uarea_id_set() to set the ID.
1000 *
1001 * @param event Event handle to get the user area ID and "set"-status of
1002 * @param[out] isset Optional output arg: has the ID been set previously?
1003 * At least one of 'isset' and 'id' must be given (or both).
1004 * @param[out] id Optional output arg into which the user area ID is
1005 * stored if it has been set before. The output arg 'isset'
1006 * should be used to determine whether 'id' has been set.
1007 * Note: 'id' will not be touched if the ID has not been set
1008 * earlier (i.e. when 'isset' is 'false').
1009 * At least one of 'isset' and 'id' must be given (or both).
1010 *
1011 * @return EM_OK if successful
1012 *
1013 * @see em_event_uarea_id_set(), em_event_uarea()
1014 * @see em_event_uarea_info() if both user area ptr and ID is needed
1015 */
1016em_status_t em_event_uarea_id(em_event_t event, bool *isset /*out*/,
1017 uint16_t *id /*out*/);
1018
1019/* Backwards compatible naming ("get") */
1020#define em_event_uarea_id_get em_event_uarea_id
1021
1022/**
1023 * @brief Set the event user area ID
1024 *
1025 * The event user area can be associated with an optional ID that e.g. can be
1026 * used to identify the contents of the actual user area data. The ID is stored
1027 * outside of the actual user area data and is available for use even if the
1028 * user area size has been set to 0 for the pool the event was allocated from.
1029 *
1030 * This function is used to set the event user area ID for the given event.
1031 * The 'set' operation overwrites any ID stored earlier.
1032 * Use em_event_uarea_id() to check whether an ID has been set earlier and
1033 * to retrieve the ID.
1034 *
1035 * @param event Event handle for which to set the user area ID
1036 * @param id The user area ID to set
1037 *
1038 * @return EM_OK if successful
1039 *
1040 * @see em_event_uarea_id(), em_event_uarea(), em_event_uarea_info()
1041 */
1042em_status_t em_event_uarea_id_set(em_event_t event, uint16_t id);
1043
1044/**
1045 * @brief Event user area information filled by em_event_uarea_info()
1046 *
1047 * Output structure for obtaining information about an event's user area.
1048 * Information related to the user area will be filled into this struct by
1049 * the em_event_uarea_info() API function.
1050 *
1051 * A user area is only present if the EM pool the event was allocated from
1052 * was created with user area size > 0, see em_pool_cfg_t and em_pool_create().
1053 * The user area ID can always be used (set/get), even when the size of the
1054 * user area is zero(0).
1055 *
1056 * @see em_event_uarea_info(), em_event_uarea_id_set()
1057 */
1058typedef struct {
1059 /** Pointer to the event user area, NULL if event has no user area */
1060 void *uarea;
1061 /** Size of the event user area, zero(0) if event has no user area */
1062 size_t size;
1063
1064 /** Event user area ID (ID can be set/get even when no uarea present) */
1065 struct {
1066 /** Boolean: has the ID been set previously? true/false */
1067 bool isset;
1068 /** Value of the user area ID, if (and only if) set before.
1069 * Only inspect '.id.value' when '.id.isset=true' indicating
1070 * that ID has been set earlier by em_event_uarea_id_set().
1071 */
1072 uint16_t value;
1073 } id;
1075
1076/**
1077 * @brief Get the event user area information for a given event.
1078 *
1079 * Obtain information about the event user area for a certain given event.
1080 * Information containing the user area pointer, size, as well as the ID is
1081 * output via the 'uarea_info' struct.
1082 * This API function combines the functionality of em_event_uarea() and
1083 * em_event_uarea_id() for use cases where both the user area pointer as
1084 * well as the ID is needed. Calling one API function instead of two might be
1085 * faster due to a fewer checks and internal conversions.
1086 *
1087 * The event user area is a fixed sized area located within the event metadata
1088 * (i.e. outside of the event payload) that can be used to store application
1089 * specific event related data without the need to adjust the payload.
1090 * The event user area is configured during EM event pool creation and thus the
1091 * size of the user area is set per pool.
1092 *
1093 * Note that the user area content is not initialized by EM, neither em_alloc()
1094 * nor em_free() will touch it and thus it might contain old user data set the
1095 * last time the area was used during a previous allocation of the same event.
1096 * Since the user area is not part of the event payload, it will not be
1097 * transmitted as part of a packet etc.
1098 *
1099 * The event user area can be associated with an optional ID that can be used to
1100 * identify the contents of the actual user area data. The ID is stored
1101 * outside of the actual user area data and is available for use even if the
1102 * user area size has been set to zero(0) for the pool the event was allocated
1103 * from. EM will initialize 'uarea_info.id.isset = false' when allocating
1104 * a new event (indicating that the ID is not set).
1105 *
1106 * @param event Event handle to get the user area information of.
1107 * @param[out] uarea_info Output struct into which the user area information
1108 * is stored.
1109 *
1110 * @return EM status code indicating success or failure of the operation.
1111 * @retval EM_OK Operation successful.
1112 * @retval Other Operation FAILED and no valid user area info could
1113 * be obtained, 'uarea_info' is all NULL/zero(0) in this case.
1114 *
1115 * @see em_pool_create() for pool specific configuration and
1116 * the EM runtime config file em-odp.conf for the default value:
1117 * 'pool.user_area_size'.
1118 * @see em_event_uarea(), em_event_uarea_id()
1119 */
1120em_status_t em_event_uarea_info(em_event_t event,
1121 em_event_uarea_info_t *uarea_info /*out*/);
1122/** @} end em_event_uarea */
1123
1124/**
1125 * @addtogroup em_event_ref
1126 * @{
1127 */
1128
1129/**
1130 * Create a reference to an event
1131 *
1132 * A reference is an additional event handle referring to an existing event.
1133 * As long as an event has multiple references, none of them (including 'event')
1134 * should be used to modify the event. Reading event data from a reference is
1135 * allowed. Writes to the event data must only be done when there is a
1136 * single event handle left, i.e. when em_event_has_ref(event) returns 'false'.
1137 * Results are undefined if these restrictions are not observed.
1138 *
1139 * The event is freed when the last reference, including the original event,
1140 * is freed.
1141 *
1142 * Currently only references to events of (major) type EM_EVENT_TYPE_PACKET can
1143 * be created. References to vector events (EM_EVENT_TYPE_VECTOR), sw buffer
1144 * events (EM_EVENT_TYPE_SW) or other event types are not supported.
1145 *
1146 * It is not allowed to use event references with event groups since assigning
1147 * an event that has references to an event group would assign all the
1148 * references to the event group resulting in undefined behaviour. E.g. using
1149 * em_send_group()/em_send_group_multi() to send a reference is wrong.
1150 *
1151 * @param event Event handle for which a reference is to be created.
1152 *
1153 * @return Reference to the event
1154 * @retval EM_EVENT_UNDEF on failure
1155 */
1156em_event_t em_event_ref(em_event_t event);
1157
1158/**
1159 * Test if an event has references
1160 *
1161 * An event that has multiple references share data with other events and thus
1162 * the (shared) data must not be modified.
1163 *
1164 * New references are created with the em_event_ref() API call. The intent of
1165 * multiple references is to avoid event copies. When a reference is created,
1166 * this function returns 'true' for both events (i.e. for the original event and
1167 * the new reference).
1168 *
1169 * @param event Event handle
1170 *
1171 * @retval false This event has no references
1172 * @retval true The event has multiple references
1173 */
1174bool em_event_has_ref(em_event_t event);
1175
1176/** @} end em_event_ref */
1177
1178/**
1179 * @addtogroup em_event_vectors
1180 * @{
1181 */
1182
1183/**
1184 * @brief Free the vector event only, not the events it contains.
1185 *
1186 * Frees only the vector event itself and not the events it contains in its
1187 * vector-table.
1188 * To free the vector event along with all events it contains,
1189 * use em_free() or em_free_multi().
1190 *
1191 * @note Passing EM_EVENT_UNDEF or a non-vector event triggers an error.
1192 * Only events of major type EM_EVENT_TYPE_VECTOR are accepted.
1193 *
1194 * @param vector_event Vector event handle
1195 */
1196void em_event_vector_free(em_event_t vector_event);
1197
1198/**
1199 * @brief Get the event vector table from an event of (major) type
1200 * EM_EVENT_TYPE_VECTOR.
1201 *
1202 * The event vector table is an array of event handles (em_event_t) stored in
1203 * a contiguous memory location for events with major event type set to
1204 * EM_EVENT_TYPE_VECTOR.
1205 * Upon completion of this function, the event table pointer of the given vector
1206 * event is returned via the output argument 'event_tbl'.
1207 *
1208 * The types of events that can be stored in the event-table depend on the
1209 * selected vector backend mode (see EM config file option 'vector.backend'):
1210 * - vector.backend = "event": events of any type can be stored
1211 * - vector.backend = "packet": only events of major type EM_EVENT_TYPE_PACKET
1212 * Invalid event handles (EM_EVENT_UNDEF) shall not be stored in the event-table.
1213 *
1214 * @param vector_event Vector event handle
1215 * @param[out] event_tbl Pointer into which the event table (ptr) is written
1216 *
1217 * @return Number of event handles currently stored (set) in the vector,
1218 * i.e. the current size. The event-table pointer can be used to
1219 * access/write entries up to max_size (see em_event_vector_max_size()),
1220 * but only entries at indices [0 ... return_value - 1] contain valid
1221 * events.
1222 * @retval 0 on error and *event_tbl is set to NULL
1223 *
1224 * @note A newly allocated vector has an empty event-table and thus the returned
1225 * size is zero until updated with em_event_vector_size_set().
1226 *
1227 * @code
1228 * em_event_type_t event_type = em_event_type(vector_event);
1229 *
1230 * if (em_event_type_major(event_type) == EM_EVENT_TYPE_VECTOR) {
1231 * em_event_t *event_tbl = NULL;
1232 * uint32_t num = em_event_vector_tbl(vector_event, &event_tbl);
1233 *
1234 * if (!num)
1235 * return;
1236 *
1237 * for (uint32_t i = 0; i < num; i++) {
1238 * event = event_tbl[i];
1239 * ... process 'event' ...
1240 * }
1241 * }
1242 * @endcode
1243 *
1244 * @see em_event_vector_size_set()
1245 */
1246uint32_t em_event_vector_tbl(em_event_t vector_event, em_event_t **event_tbl/*out*/);
1247
1248/**
1249 * Return the event type of events stored in the event vector table.
1250 *
1251 * The vector event itself has major type EM_EVENT_TYPE_VECTOR, but the events
1252 * stored in its event table have their own major type. This function returns
1253 * that event table type. The special type EM_EVENT_TYPE_ANY indicates that the
1254 * vector contains multiple event types or that the type is unknown.
1255 *
1256 * After allocation (em_alloc() etc.), before any events are added, the event
1257 * table type depends on the selected vector backend mode as follows (see the
1258 * EM config file option 'vector.backend'):
1259 * 1) vector.backend = "event": type is initialized to EM_EVENT_TYPE_ANY
1260 * 2) vector.backend = "packet": type is initialized to EM_EVENT_TYPE_PACKET
1261 * Event aggregators set the table type to the event type common to all events
1262 * or to EM_EVENT_TYPE_ANY if the events are mixed or the type cannot be
1263 * determined. The table type can also be set with em_event_vector_type_set().
1264 *
1265 * @param event_vector Event handle of the event vector
1266 *
1267 * @return Event type
1268 * @retval EM_EVENT_TYPE_UNDEF on error
1269 */
1270em_event_type_t em_event_vector_type(em_event_t event_vector);
1271
1272/**
1273 * Set the type of the events stored in the event vector table.
1274 *
1275 * The specified type is stored in vector metadata and can be queried later
1276 * with em_event_vector_type(). The type must match the vector contents when
1277 * the vector is passed to an EM API.
1278 *
1279 * The set type must apply to all events stored in the vector's event-table,
1280 * otherwise the result is undefined when the vector is passed to an EM API.
1281 *
1282 * The table type that can be set depends on the selected vector backend mode
1283 * as follows (see the EM config file option 'vector.backend'):
1284 * 1) vector.backend = "event": all event types are supported and can be set.
1285 * Use EM_EVENT_TYPE_ANY if the vector contains multiple event types or if
1286 * the type is unknown, otherwise use the common event type of all entries.
1287 * 2) vector.backend = "packet": only types with the major part set to
1288 * EM_EVENT_TYPE_PACKET are accepted.
1289 *
1290 * This call is not needed if the current table type already matches the
1291 * updated contents.
1292 *
1293 * @param event_vector Event handle of the event vector
1294 * @param type Event type
1295 *
1296 * @return EM_OK on success
1297 * @retval Other on failure (e.g. invalid event, invalid type or
1298 * type not compatible with the vector backend mode)
1299 */
1300em_status_t em_event_vector_type_set(em_event_t event_vector,
1301 em_event_type_t type);
1302
1303/**
1304 * @brief Number of event handles available (set) in a vector.
1305 *
1306 * Returns the number of available events in the vector.
1307 * Note that the returned 'size' indicates how many valid events are stored in
1308 * the vector's event-table.
1309 * The 'size' neither indicates the alloc-size (size given to em_alloc()) nor
1310 * the max-size of the event-table, use em_event_vector_max_size() or
1311 * em_event_vector_info() to obtain that information.
1312 *
1313 * The types of events that can be stored in the event-table depend on the
1314 * selected vector backend mode (see EM config file option 'vector.backend'):
1315 * - vector.backend = "event": events of any type can be stored
1316 * - vector.backend = "packet": only events of major type EM_EVENT_TYPE_PACKET
1317 *
1318 * @param vector_event Vector event handle
1319 *
1320 * @return The number of event handles available (set) in the vector
1321 *
1322 * @note A newly allocated vector has an empty event-table and thus the returned
1323 * size is zero until updated with em_event_vector_size_set()
1324 */
1325uint32_t em_event_vector_size(em_event_t vector_event);
1326
1327/**
1328 * @brief Set the number of event handles stored in a vector
1329 *
1330 * Update the number of event handles stored in a vector.
1331 * This function shall be used to set the number of events available in the
1332 * given vector when the application itself is producing (or updating) the
1333 * event vector. Only valid event handles can be stored into the vector's
1334 * event-table. The events must be stored into the vector before setting the
1335 * size, i.e. first add/remove events to/from the vector's event-table (within
1336 * max-size limits) and only then set the size.
1337 *
1338 * The types of events that can be stored in the event-table depend on the
1339 * selected vector backend mode (see EM config file option 'vector.backend'):
1340 * - vector.backend = "event": events of any type can be stored
1341 * - vector.backend = "packet": only events of major type EM_EVENT_TYPE_PACKET
1342 *
1343 * @param vector_event Vector event handle
1344 * @param size Number of event handles in the vector
1345 *
1346 * @note The maximum number of event handles the vector can hold is defined by
1347 * em_pool_cfg_t::subpool[i].size or can be obtained for a specific vector
1348 * with em_event_vector_max_size().
1349 *
1350 * @note All handles in the vector table (0 ... size - 1) must be valid
1351 * EM event handles (EM_EVENT_UNDEF not allowed).
1352 *
1353 * @note Setting 'size' larger than the vector's max_size
1354 * (see em_event_vector_max_size()) results in undefined behavior.
1355 * EM may report this as an error depending on the check level.
1356 */
1357void em_event_vector_size_set(em_event_t vector_event, uint32_t size);
1358
1359/**
1360 * @brief Maximum number of event handles that can be stored in a vector.
1361 *
1362 * Returns the maximum number of events that can be stored into the event-table
1363 * of the given vector event, i.e. the max-size that can be used with
1364 * em_event_vector_size_set().
1365 * The max-size might be larger than the size requested during allocation and
1366 * instead reflects the vector-size used when creating the EM event vector pool.
1367 *
1368 * @param vector_event Vector event handle
1369 *
1370 * @return The maximum number of event handles that can be stored in the vector
1371 * @retval >0 on success
1372 * @retval 0 on failure or if EM cannot retrieve the max size (non-EM pool).
1373 */
1374uint32_t em_event_vector_max_size(em_event_t vector_event);
1375
1376/**
1377 * @brief Vector event information filled by em_event_vector_info()
1378 *
1379 * Output structure for obtaining information about a vector event.
1380 * Information related to the vector event will be filled into this struct by
1381 * the em_event_vector_info() API function.
1382 */
1383typedef struct {
1384 /**
1385 * Event type of events stored in the vector's event-table.
1386 * EM_EVENT_TYPE_ANY if the vector contains mixed types or the type
1387 * is unknown. EM_EVENT_TYPE_UNDEF on error.
1388 * @see em_event_vector_type() for details on default values per
1389 * vector backend mode.
1390 */
1392 /**
1393 * Pointer to the vector's event-table.
1394 * NULL on error.
1395 */
1396 em_event_t *event_tbl;
1397 /**
1398 * Number of available/set valid events in the vector's event-table.
1399 * 0 on error or if the vector is newly allocated and thus has an empty
1400 * event-table.
1401 */
1402 uint32_t size;
1403 /**
1404 * Max number of events that can fit into the vector's event-table,
1405 * 0 on failure or if EM cannot retrieve the max size (non-EM pool).
1406 */
1407 uint32_t max_size;
1409
1410/**
1411 * @brief Retrieve information about the given vector event.
1412 *
1413 * Vector event information is output via the struct 'vector_info'.
1414 * Combines em_event_vector_tbl(), em_event_vector_size() and
1415 * em_event_vector_max_size() into one function call.
1416 *
1417 * @param vector_event Vector event handle to get the information of.
1418 * @param[out] vector_info Output struct into which the vector information
1419 * is stored.
1420 *
1421 * @return EM status code indicating success or failure of the operation.
1422 * @retval EM_OK Operation successful.
1423 * @retval Other Operation FAILED and no valid vector info could
1424 * be obtained, 'vector_info' is all NULL/zero(0) in this case.
1425 */
1426em_status_t em_event_vector_info(em_event_t vector_event,
1427 em_event_vector_info_t *vector_info /*out*/);
1428
1429/** @} end em_event_vectors */
1430
1431/**
1432 * Convert an event handle to an unsigned integer
1433 *
1434 * @param event Event handle to be converted
1435 * @return uint64_t value that can be used to print/display the handle
1436 *
1437 * @note This routine is intended to be used for diagnostic purposes
1438 * to enable applications to e.g. generate a printable value that represents
1439 * an em_event_t handle.
1440 */
1441uint64_t em_event_to_u64(em_event_t event);
1442
1443/**
1444 * @}
1445 */
1446#ifdef __cplusplus
1447}
1448#endif
1449
1450#pragma GCC visibility pop
1451#endif /* EVENT_MACHINE_EVENT_H_ */
uint32_t em_event_type_t
uint32_t em_status_t
em_event_t em_event_ref(em_event_t event)
bool em_event_has_ref(em_event_t event)
em_status_t em_event_uarea_id(em_event_t event, bool *isset, uint16_t *id)
Get the event user area ID along with information if it has been set.
em_status_t em_event_uarea_id_set(em_event_t event, uint16_t id)
Set the event user area ID.
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.
void * em_event_uarea(em_event_t event, size_t *size)
Get a pointer to the event user area, optionally along with its size.
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.
uint32_t em_event_vector_max_size(em_event_t vector_event)
Maximum number of event handles that can be stored in a vector.
em_status_t em_event_vector_type_set(em_event_t event_vector, em_event_type_t type)
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.
void em_event_vector_free(em_event_t vector_event)
Free the vector event only, not the events it contains.
uint32_t em_event_vector_size(em_event_t vector_event)
Number of event handles available (set) in a vector.
void em_event_vector_size_set(em_event_t vector_event, uint32_t size)
Set the number of event handles stored in a vector.
em_event_type_t em_event_vector_type(em_event_t event_vector)
em_event_t em_event_clone(em_event_t event, em_pool_t pool)
Clone an event.
int em_event_same_type_multi(const em_event_t events[], int num, em_event_type_t *same_type)
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.
em_event_type_t em_event_type(em_event_t event)
uint32_t em_event_size(em_event_t event)
int em_send_multi(const em_event_t events[], int num, em_queue_t queue)
int em_alloc_multi(em_event_t events[], int num, uint32_t size, em_event_type_t type, em_pool_t pool)
void em_event_mark_free(em_event_t event)
Mark the event as "free".
em_status_t em_event_unmark_send(em_event_t event)
em_event_t em_alloc(uint32_t size, em_event_type_t type, em_pool_t pool)
void em_event_unmark_free(em_event_t event)
Unmark an event previously marked as "free" (i.e mark as "allocated" again).
void em_event_mark_free_multi(const em_event_t events[], int num)
Mark multiple events as "free".
void em_event_unmark_free_multi(const em_event_t events[], int num)
Unmark multiple events previously marked as "free".
em_status_t em_event_mark_send(em_event_t event, em_queue_t queue)
void em_free_multi(em_event_t events[], int num)
em_pool_t em_event_pool(em_event_t event)
Returns the EM event-pool the event was allocated from.
em_status_t em_event_set_type(em_event_t event, em_event_type_t newtype)
int em_event_type_multi(const em_event_t events[], int num, em_event_type_t types[])
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.
em_pool_t em_event_pool_subpool(em_event_t event, int *subpool)
Returns the EM event-pool and subpool the event was allocated from.
uint64_t em_event_to_u64(em_event_t event)
em_status_t em_send(em_event_t event, em_queue_t queue)
em_event_type_major_e
void em_free(em_event_t event)
em_event_type_sw_minor_e
void * em_event_pointer(em_event_t event)
@ EM_EVENT_TYPE_SW
@ EM_EVENT_TYPE_UNDEF
@ EM_EVENT_TYPE_ODP
@ EM_EVENT_TYPE_PACKET
@ EM_EVENT_TYPE_TIMER_IND
@ EM_EVENT_TYPE_ANY
@ EM_EVENT_TYPE_TIMER
@ EM_EVENT_TYPE_CRYPTO
@ EM_EVENT_TYPE_VECTOR
Event user area information filled by em_event_uarea_info()
Vector event information filled by em_event_vector_info()