EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
em_event_types.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015-2021, 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 /**
32 * @file
33 * EM internal event types & definitions
34 *
35 */
36
37#ifndef EM_EVENT_TYPES_H_
38#define EM_EVENT_TYPES_H_
39
40#include <stddef.h> /* offsetof */
41#include <stdint.h>
42
43#include <odp_api.h>
44
45#include <event_machine.h>
47
48#include "misc/list.h"
49
50#ifdef __cplusplus
51extern "C" {
52#endif
53
54COMPILE_TIME_ASSERT(sizeof(em_event_t) == sizeof(odp_event_t),
55 EM_EVENT_SIZE_MISMATCH);
56
57/**
58 * @def USER_FLAG_SET
59 *
60 * Used to detect whether the event's event-header has been initialized by EM.
61 *
62 * Set the odp-pkt/vector user-flag to be able to recognize events that EM has
63 * created vs. events from pkt-input that needs their ev-hdrs to be initialized
64 * before further EM processing.
65 */
66#define USER_FLAG_SET 1
67
68/**
69 * Internal representation of the event handle (em_event_t) when using
70 * Event State Verification (ESV)
71 *
72 * An event-generation-count is encoded into the high bits of the event handle
73 * to catch illegal usage after the event ownership has been transferred.
74 * Each user-to-EM event state transition increments the .evgen and thus
75 * obsoletes any further use of the handle by that user.
76 */
77typedef union {
78 em_event_t event;
79 struct {
80#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
81 uint64_t evptr : 48;
82 uint64_t evgen : 16;
83#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
84 uint64_t evgen : 16;
85 uint64_t evptr : 48;
86#endif
87 };
88} evhdl_t;
89
90COMPILE_TIME_ASSERT(sizeof(evhdl_t) == sizeof(em_event_t), EVHDL_T_SIZE_ERROR);
91
92/**
93 * Stash entry for EM Atomic Groups internal stashes and Local Queue storage
94 * Stash a combo of dst-queue and event as one 64-bit value into the stash.
95 */
96typedef union {
97 uint64_t u64;
98 struct {
99#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
100 uint64_t evptr : 48;
101 uint64_t qidx : 16;
102#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
103 uint64_t qidx : 16;
104 uint64_t evptr : 48;
105#endif
106 };
108
109COMPILE_TIME_ASSERT(sizeof(stash_entry_t) == sizeof(uint64_t),
110 STASH_ENTRY_T_SIZE_ERROR);
111
112/**
113 * Event-state counters: 'evgen', 'ref_cnt' and 'send_cnt'.
114 *
115 * Atomically updated as one single var via 'evstate_cnt_t::u64'.
116 */
117typedef union ODP_ALIGNED(sizeof(uint64_t)) {
118 uint64_t u64; /* updated atomically in the event-hdr */
119 struct {
120 uint16_t evgen;
121 uint16_t rsvd;
122 uint16_t ref_cnt;
123 uint16_t send_cnt;
124 };
125} evstate_cnt_t;
126
127/* Verify size of struct, i.e. accept no padding */
128COMPILE_TIME_ASSERT(sizeof(evstate_cnt_t) == sizeof(uint64_t),
129 EVSTATE_CNT_T_SIZE_ERROR);
130
131/**
132 * Event state information, updated on valid state transitions.
133 * "Best effort" update, i.e. atomic update of state is not
134 * guaranteed in invalid simultaneous state updates.
135 *
136 * Contains the previously known good state and will be
137 * printed when detecting an invalid state transition.
138 */
139typedef struct ODP_PACKED {
140 /**
141 * First 'word' of the event payload as seen
142 * at the time of the previous state update.
143 */
145
146 /**
147 * EO-index
148 *
149 * Obtained from the EO with eo_hdl2idx(eo) to save hdr space.
150 */
151 int16_t eo_idx;
152
153 /**
154 * Queue-index
155 *
156 * Obtained from the queue with queue_hdl2idx(queue) to save hdr space
157 */
158 int16_t queue_idx;
159
160 /**
161 * EM API operation ID.
162 * Identifies the previously called API func that altered state
163 */
164 uint8_t api_op;
165 /** EM core that called API('api_op') */
166 uint8_t core;
168
169/**
170 * Event User Area metadata in the event header
171 */
172typedef union {
173 uint32_t all;
174 struct {
175 /** is the user area id set? */
176 uint32_t isset_id : 1;
177 /** is the uarea initialized? */
178 uint32_t isinit : 1;
179 /** requested size (bytes), <= EM_EVENT_USER_AREA_MAX_SIZE */
180 uint32_t size : 14;
181 /** user area id */
182 uint32_t id : 16;
183 };
185
186COMPILE_TIME_ASSERT(sizeof(ev_hdr_user_area_t) == sizeof(uint32_t),
187 EV_HDR_USER_AREA_T_SIZE_ERROR);
188
189/**
190 * Event header
191 *
192 * SW & I/O originated events.
193 */
194typedef struct event_hdr {
195 /**
196 * Event State Verification (ESV) counters.
197 *
198 * Together the evstate_cnt_t counters (evgen, ref_cnt
199 * and send_cnt) can be used to detect invalid states
200 * and operations on the event, e.g.:
201 * double-free, double-send, send-after-free,
202 * free-after-send, usage-after-output,
203 * usage-after-timer-tmo-set/ack/cancel/delete etc.
204 */
205 evstate_cnt_t state_cnt;
206
207 /**
208 * Event State Verification (ESV) state.
209 *
210 * Event state, updated on valid state transitions.
211 * "Best effort" update, i.e. atomic update not
212 * guaranteed in invalid simultaneous state-updates.
213 *
214 * Contains the previously known good state and will be
215 * printed when detecting an invalid state transition.
216 */
218
219 /**
220 * Event flags
221 */
222 union {
223 uint8_t all;
224 struct {
225 /**
226 * Indicate that this event has (or had) references and
227 * some of the ESV checks must be omitted (evgen).
228 * Will be set for the whole lifetime of the event.
229 */
230 uint8_t refs_used : 1;
231 /**
232 * Indicate that this event is used as tmo indication.
233 * See em_tmo_type_t. Initially 0 = EM_TMO_TYPE_NONE
234 */
235 uint8_t tmo_type : 2;
236 /**
237 * Indicate that the .vector_type field is set
238 * by EM and contains a valid value.
239 */
240 uint8_t vectype_set : 1;
241 /**
242 * Indicate that the event is enqueued by the user to an
243 * EM_QUEUE_TYPE_AGGR queue. Allows dispatch to apply
244 * the missing em2usr ESV transition for inner events of
245 * aggregation-produced vectors when received as vector.
246 * Cleared after the transition.
247 */
248 uint8_t aggr_sent : 1;
249 /** currently unused bits */
250 uint8_t unused : 3;
251 };
253
254 /**
255 * Payload alloc alignment offset.
256 * Value is copied from pool_elem->align_offset for easy access.
257 */
259
260 /**
261 * Event type, contains major and minor parts
262 */
264
265 /**
266 * Event handle (this event)
267 */
268 em_event_t event;
269
270 /**
271 * Event size
272 *
273 * buf: current size
274 * pkt & vec: original alloc size (otherwise not used, odp size used)
275 * periodic ring timer tmo (EM_EVENT_TYPE_TIMER_IND): 0
276 */
277 uint32_t event_size;
278
279 /**
280 * Event group generation
281 */
282 uint32_t egrp_gen;
283
284 /**
285 * Event Group handle (cannot be used by event references)
286 */
287 em_event_group_t egrp;
288
289 /**
290 * Holds the tmo handle in case event is used as timeout indication.
291 * Only valid if flags.tmo_type is not EM_TMO_TYPE_NONE (0).
292 * Initialized only when used as timeout indication by timer code.
293 */
295
296 /**
297 * Event User Area metadata
298 */
300
301 /**
302 * Event type of the events in the vector.
303 * Used by events of (major) type EM_EVENT_TYPE_VECTOR and specifies the
304 * type of all events in the vector's event table (em_event_t ev_tbl[]).
305 * Only valid if flags.vectype_set = 1, otherwise the vector type is
306 * considered not set by EM yet.
307 * Can also be EM_EVENT_TYPE_ANY, see em_event_type_t.
308 */
310
311 /**
312 * End of event header data,
313 * for offsetof(event_hdr_t, end_hdr_data)
314 */
315 uint8_t end_hdr_data[0];
316
317 /*
318 * ! EMPTY SPACE !
319 */
320
321 void *end[0] ODP_ALIGNED(8); /* pad to next 8B boundary */
323
324COMPILE_TIME_ASSERT(sizeof(event_hdr_t) <= 64, EVENT_HDR_SIZE_ERROR);
325COMPILE_TIME_ASSERT(sizeof(event_hdr_t) % sizeof(uint64_t) == 0, EVENT_HDR_SIZE_ERROR2);
326
327/**
328 * Event header used only when pre-allocating the pool during pool creation to
329 * be able to link all the event headers together into a linked list.
330 * Make sure not to overwrite the event state information in the header with the
331 * linked list information.
332 */
333typedef union event_prealloc_hdr {
334 event_hdr_t ev_hdr;
335
336 struct {
337 uint8_t u8[sizeof(event_hdr_t) - sizeof(list_node_t)];
338 /**
339 * Pool pre-allocation: allocate and link each event in the pool into a
340 * linked list to be able to initialize the event state into a known
341 * state for ESV.
342 */
344 };
346
347COMPILE_TIME_ASSERT(sizeof(event_prealloc_hdr_t) == sizeof(event_hdr_t),
348 EVENT_PREALLOC_HDR_SIZE_ERROR);
349COMPILE_TIME_ASSERT(offsetof(event_prealloc_hdr_t, list_node) >
350 offsetof(event_hdr_t, state) + sizeof(ev_hdr_state_t),
351 EVENT_PREALLOC_HDR_SIZE_ERROR2);
352COMPILE_TIME_ASSERT(offsetof(event_prealloc_hdr_t, list_node) >
353 offsetof(event_hdr_t, event) + sizeof(em_event_t),
354 EVENT_PREALLOC_HDR_SIZE_ERROR3);
355
356#ifdef __cplusplus
357}
358#endif
359
360#endif /* EM_EVENT_TYPES_H_ */
union event_prealloc_hdr event_prealloc_hdr_t
union ODP_ALIGNED(sizeof(uint64_t))
struct ODP_PACKED ev_hdr_state_t
struct event_hdr event_hdr_t
uint32_t em_event_type_t
uint32_t payload_first
int16_t queue_idx
uint8_t refs_used
ev_hdr_state_t state
em_event_t event
uint8_t align_offset
em_tmo_t tmo
uint8_t tmo_type
evstate_cnt_t state_cnt
ev_hdr_user_area_t user_area
uint8_t end_hdr_data[0]
uint8_t aggr_sent
uint8_t vectype_set
union event_hdr::@43 flags
uint32_t event_size
em_event_type_t event_type
em_event_group_t egrp
em_event_type_t vector_type
uint8_t unused
uint32_t egrp_gen