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