EM-ODP  3.7.0
Event Machine on ODP
em_queue_types.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015, 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 queue types & definitions
34  *
35  */
36 
37 #ifndef EM_QUEUE_TYPES_H_
38 #define EM_QUEUE_TYPES_H_
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /*
45  * EM internal queue ids - local part of the queue only, i.e missing the
46  * device-id.
47  * Note that the EM queue handle range is determined by 'EM_QUEUE_RANGE_OFFSET'
48  */
49 #define MAX_INTERNAL_QUEUES ROUND_UP(EM_MAX_CORES + 1, 32)
50 
51 #define _FIRST_INTERNAL_QUEUE (_EM_QUEUE_STATIC_MAX + 1)
52 #define FIRST_INTERNAL_QUEUE ((uint16_t)_FIRST_INTERNAL_QUEUE)
53 
54 #define _LAST_INTERNAL_QUEUE (_FIRST_INTERNAL_QUEUE + MAX_INTERNAL_QUEUES - 1)
55 #define LAST_INTERNAL_QUEUE ((uint16_t)_LAST_INTERNAL_QUEUE)
56 
57 #define FIRST_INTERNAL_UNSCHED_QUEUE (FIRST_INTERNAL_QUEUE)
58 #define SHARED_INTERNAL_UNSCHED_QUEUE (LAST_INTERNAL_QUEUE)
59 
60 /* Priority for the EM-internal queues */
61 #define INTERNAL_QUEUE_PRIORITY (EM_QUEUE_PRIO_HIGHEST)
62 
63 COMPILE_TIME_ASSERT(MAX_INTERNAL_QUEUES - 1 >= EM_MAX_CORES,
64  TOO_FEW_INTERNAL_QUEUES_ERROR);
65 
66 /* Dynamic queue ids */
67 #define _FIRST_DYN_QUEUE (_LAST_INTERNAL_QUEUE + 1)
68 #define FIRST_DYN_QUEUE ((uint16_t)_FIRST_DYN_QUEUE)
69 
70 COMPILE_TIME_ASSERT(_FIRST_DYN_QUEUE > _LAST_INTERNAL_QUEUE,
71  FIRST_DYN_QUEUE_ERROR);
72 
73 #define QUEUE_ELEM_VALID ((uint16_t)0xCAFE)
74 
75 /* Verify that the byte order is defined for 'internal_queue_t' */
76 #if \
77 (__BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__) && \
78 (__BYTE_ORDER__ != __ORDER_BIG_ENDIAN__)
79 #error __BYTE_ORDER__ not defined!
80 #endif
81 
82 /**
83  * Queue create-params passed to queue_setup...()
84  */
85 typedef struct {
86  const char *name;
87  em_queue_type_t type;
88  em_queue_prio_t prio;
89  em_atomic_group_t atomic_group;
90  em_queue_group_t queue_group;
91  const em_queue_conf_t *conf;
93 
94 /**
95  * Internal representation of the EM queue handle
96  * The EM queue handle contains a 16-bit queue-id and a 16-bit device-id.
97  */
98 typedef union {
99  em_queue_t queue;
100  struct {
101 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
102  uint16_t queue_id;
103  uint16_t device_id;
104 #ifdef EM_64_BIT
105  uint32_t unused;
106 #endif
107 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
108 #ifdef EM_64_BIT
109  uint32_t unused;
110 #endif
111  uint16_t device_id;
112  uint16_t queue_id;
113 #endif
114  };
116 
117 /* Verify size of struct, i.e. accept no padding */
118 COMPILE_TIME_ASSERT(sizeof(internal_queue_t) == sizeof(em_queue_t),
119  INTERNAL_QUEUE_T_SIZE_ERROR);
120 
121 /**
122  * Queue state
123  */
124 typedef enum queue_state {
125  /** Invalid queue state, queue not created/allocated */
127 
128  /*
129  * Scheduled queue (ATOMIC, PARALLEL, ORDERED) states:
130  * (keep state values consecutive: ...n-1,n,n+1...)
131  */
132  /** Queue initialization, allocated and being set up */
134  /** Queue added/bound to an EO, but EO-start not yet complete */
136  /** Queue ready, related EO started */
138 
139  /*
140  * Non-scheduled queue (UNSCHED, OUTPUT) state use the UNSCHEDULED-state.
141  */
142  /* Use separate value for unscheduled queues to catch illegal usage */
143  EM_QUEUE_STATE_UNSCHEDULED = 255
144 } queue_state_e;
145 /**
146  * Queue state, packed into uint8_t.
147  *
148  * The 'enum queue_state' or queue_state_e will always fit into an uint8_t.
149  * Save space in the queue_elem_t by using this instead.
150  */
151 typedef uint8_t queue_state_t;
152 
153 /**
154  * Atomic-group queue specific part of the queue element
155  */
156 typedef struct q_elem_atomic_group_ {
157  /** The atomic group handle (if any) of this queue */
158  em_atomic_group_t atomic_group;
159  /** List node for linking queue elems belonging to an atomic group */
162 
163 /**
164  * Output queue specific part of the queue element
165  */
166 typedef struct q_elem_output_ {
167  /** Output Queue config, incl. output_fn(..., output_fn_args) */
169  /** Copied output_fn_args content of length 'args_len' stored in event */
171  /** Output queue index used for output queue tracking, not same as queue index */
172  uint32_t idx;
173  /** Lock for output queues during an ordered-context */
174  env_spinlock_t lock;
176 
177 /**
178  * EM queue element
179  */
180 typedef struct queue_elem_t {
181  /**
182  * Check that contents is an EM queue elem.
183  *
184  * EM will verify that the ODP queue context actually points to an
185  * EM queue elem and not to something else:
186  * queue_elem_t *q_elem = odp_queue_context(odp_queue);
187  * if (!q_elem || q_elem->valid_check != QUEUE_ELEM_VALID)
188  * EM_ERROR(...);
189  * Keep first.
190  */
191  uint16_t valid_check;
192 
193  union {
194  uint8_t all;
195  struct {
196  /* true:receive_multi_func(), false:receive_func() */
197  uint8_t use_multi_rcv : 1;
198  /** set if queue is scheduled, i.e. atomic, parallel or ordered */
199  uint8_t scheduled : 1;
200  /** Does this queue belong to an EM Atomic Group (true/false)? */
201  uint8_t in_atomic_group : 1;
202  /** Is this an ODP pktin event queue (true/false)? */
203  uint8_t is_pktin : 1;
204  /** reserved bits */
205  uint8_t rsvd : 4;
206  };
207  } flags;
208 
209  /** Queue state */
210  queue_state_t state; /* queue_state_e */
211 
212  /** Queue priority */
213  uint8_t priority; /* em_queue_prio_t */
214 
215  /** Atomic, parallel, ordered, unscheduled, local, output */
216  uint8_t type; /* em_queue_type_t */
217 
218  /** Max number of events passed to the EO's multi-event receive function */
219  uint16_t max_events; /* only used if flags.use_multi_rcv == true */
220 
221  /** EM EO that this queue belongs to */
222  uint16_t eo; /* em_eo_t */
223 
224  /** Queue handle */
225  uint32_t queue; /* em_queue_t */
226 
227  /** Associated ODP queue handle */
228  odp_queue_t odp_queue;
229 
230  /** User defined queue context (can be NULL) */
231  void *context;
232 
233  union {
234  /** Copy of the event receive function for better performance */
236  /** Copy of the multi-event receive function for better performance */
238  };
239 
240  /** Copy of the user defined eo context (or NULL) for performance */
241  void *eo_ctx;
242 
243  union {
245  q_elem_output_t output;
246  };
247 
248  /** Associated eo element */
250 
251  /** Queue group handle of this queue */
252  em_queue_group_t queue_group;
253 
254  /** List node for linking queue elems belonging to an EO */
256  /** List node for linking queue elems belonging to a queue group */
258  /** Queue pool elem for linking free queues for queue_alloc() */
260 
261  /** Guarantee that size is a multiple of cache line size */
264 
265 COMPILE_TIME_ASSERT(sizeof(queue_elem_t) % ENV_CACHE_LINE_SIZE == 0,
266  QUEUE_ELEM_T__SIZE_ERROR);
267 
268 /**
269  * EM queue element table
270  */
271 typedef struct queue_tbl_t {
272  /** ODP queue capabilities common for all queues */
273  odp_queue_capability_t odp_queue_capability;
274  /** ODP schedule capabilities related to queues */
275  odp_schedule_capability_t odp_schedule_capability;
276  /** Current number of allocated output queues */
278  /** Free output queue indexes */
280  /** Lock for output queue (de-)allocations */
281  env_spinlock_t output_queue_lock;
282 
283  /**
284  * Dynamically allocated memory starts here. The elements
285  * are in a single continuous memory block. The amount of memory
286  * reserved depends on the max number of EM queues given in
287  * EM config file.
288  */
289  /** Queue element table, format: queue_elem[em_queue_get_max_num()] */
291  /** Queue name table, format: name[em_queue_get_max_num()][EM_QUEUE_NAME_LEN] */
293 } queue_tbl_t;
294 
295 /**
296  * Pool of free queues
297  */
298 typedef struct queue_pool_t {
299  objpool_t objpool;
300 } queue_pool_t;
301 
302 /**
303  * Local queues, i.e. core-local storage for events to local queues
304  */
305 typedef struct local_queues_t {
306  int empty;
307  struct {
308  int empty_prio;
309  odp_stash_t stash;
310  } prio[EM_QUEUE_PRIO_NUM];
312 
313 /**
314  * Track output-queues used during a dispatch round (burst)
315  */
316 typedef struct output_queue_track_t {
317  unsigned int idx_cnt;
318  uint16_t idx[EM_MAX_OUTPUT_QUEUES];
319  queue_elem_t *used_queues[EM_MAX_OUTPUT_QUEUES];
321 
322 #ifdef __cplusplus
323 }
324 #endif
325 
326 #endif /* EM_QUEUE_TYPES_H_ */
queue_elem_t::eo_ctx
void * eo_ctx
Definition: em_queue_types.h:241
queue_elem_t::queue_group
em_queue_group_t queue_group
Definition: em_queue_types.h:252
EM_QUEUE_STATE_BIND
@ EM_QUEUE_STATE_BIND
Definition: em_queue_types.h:135
queue_pool_t
struct queue_pool_t queue_pool_t
EM_QUEUE_PRIO_NUM
#define EM_QUEUE_PRIO_NUM
Definition: event_machine_hw_config.h:103
em_queue_conf_t
Definition: event_machine_types.h:212
EM_QUEUE_STATE_INVALID
@ EM_QUEUE_STATE_INVALID
Definition: em_queue_types.h:126
queue_pool_t
Definition: em_queue_types.h:298
q_elem_atomic_group_t
struct q_elem_atomic_group_ q_elem_atomic_group_t
queue_elem_t::max_events
uint16_t max_events
Definition: em_queue_types.h:219
queue_tbl_t::odp_queue_capability
odp_queue_capability_t odp_queue_capability
Definition: em_queue_types.h:273
ENV_CACHE_LINE_SIZE
#define ENV_CACHE_LINE_SIZE
Definition: environment.h:62
queue_elem_t::is_pktin
uint8_t is_pktin
Definition: em_queue_types.h:203
queue_elem_t::receive_multi_func
em_receive_multi_func_t receive_multi_func
Definition: em_queue_types.h:237
queue_elem_t::eo_elem
eo_elem_t * eo_elem
Definition: em_queue_types.h:249
queue_elem_t::ENV_CACHE_LINE_ALIGNED
void *end[0] ENV_CACHE_LINE_ALIGNED
Definition: em_queue_types.h:262
queue_elem_t::type
uint8_t type
Definition: em_queue_types.h:216
queue_elem_t::queue_pool_elem
objpool_elem_t queue_pool_elem
Definition: em_queue_types.h:259
EM_QUEUE_STATE_INIT
@ EM_QUEUE_STATE_INIT
Definition: em_queue_types.h:133
queue_tbl_t::name
char(* name)[EM_QUEUE_NAME_LEN]
Definition: em_queue_types.h:292
ENV_CACHE_LINE_ALIGNED
struct queue_elem_t ENV_CACHE_LINE_ALIGNED
queue_elem_t::queue_node
list_node_t queue_node
Definition: em_queue_types.h:255
q_elem_output_::lock
env_spinlock_t lock
Definition: em_queue_types.h:174
queue_tbl_t::ENV_CACHE_LINE_ALIGNED
env_atomic32_t output_queue_count ENV_CACHE_LINE_ALIGNED
Definition: em_queue_types.h:277
output_queue_track_t
Definition: em_queue_types.h:316
queue_elem_t::state
queue_state_t state
Definition: em_queue_types.h:210
list_node_t
Definition: list.h:42
em_queue_type_t
uint32_t em_queue_type_t
Definition: event_machine_types.h:168
queue_tbl_t::ENV_CACHE_LINE_ALIGNED
queue_elem_t *queue_elem ENV_CACHE_LINE_ALIGNED
Definition: em_queue_types.h:290
queue_tbl_t::output_queue_lock
env_spinlock_t output_queue_lock
Definition: em_queue_types.h:281
EM_QUEUE_NAME_LEN
#define EM_QUEUE_NAME_LEN
Definition: event_machine_config.h:125
q_elem_output_::output_conf
em_output_queue_conf_t output_conf
Definition: em_queue_types.h:168
eo_elem_t
Definition: em_eo_types.h:47
em_output_queue_conf_t
Definition: event_machine_hw_types.h:396
queue_tbl_t::odp_schedule_capability
odp_schedule_capability_t odp_schedule_capability
Definition: em_queue_types.h:275
queue_state
queue_state
Definition: em_queue_types.h:124
queue_setup_t
Definition: em_queue_types.h:85
queue_elem_t::odp_queue
odp_queue_t odp_queue
Definition: em_queue_types.h:228
queue_elem_t::queue
uint32_t queue
Definition: em_queue_types.h:225
q_elem_atomic_group_
Definition: em_queue_types.h:156
queue_elem_t::context
void * context
Definition: em_queue_types.h:231
queue_state_t
uint8_t queue_state_t
Definition: em_queue_types.h:151
queue_elem_t::in_atomic_group
uint8_t in_atomic_group
Definition: em_queue_types.h:201
queue_tbl_t
Definition: em_queue_types.h:271
objpool_t
Definition: objpool.h:64
queue_elem_t::receive_func
em_receive_func_t receive_func
Definition: em_queue_types.h:235
queue_elem_t::scheduled
uint8_t scheduled
Definition: em_queue_types.h:199
EM_QUEUE_STATE_READY
@ EM_QUEUE_STATE_READY
Definition: em_queue_types.h:137
_env_atomic32
Definition: env_atomic.h:44
queue_tbl_t
struct queue_tbl_t queue_tbl_t
queue_elem_t::priority
uint8_t priority
Definition: em_queue_types.h:213
queue_elem_t::valid_check
uint16_t valid_check
Definition: em_queue_types.h:191
objpool_elem_t
Definition: objpool.h:48
q_elem_output_
Definition: em_queue_types.h:166
em_receive_multi_func_t
void(* em_receive_multi_func_t)(void *eo_ctx, em_event_t events[], int num, em_queue_t queue, void *q_ctx)
Definition: event_machine_eo.h:189
q_elem_output_::output_fn_args_event
em_event_t output_fn_args_event
Definition: em_queue_types.h:170
queue_elem_t::eo
uint16_t eo
Definition: em_queue_types.h:222
local_queues_t
Definition: em_queue_types.h:305
q_elem_atomic_group_::agrp_node
list_node_t agrp_node
Definition: em_queue_types.h:160
output_queue_track_t
struct output_queue_track_t output_queue_track_t
em_receive_func_t
void(* em_receive_func_t)(void *eo_ctx, em_event_t event, em_event_type_t type, em_queue_t queue, void *q_ctx)
Definition: event_machine_eo.h:149
em_queue_prio_t
uint32_t em_queue_prio_t
Definition: event_machine_types.h:186
queue_elem_t::rsvd
uint8_t rsvd
Definition: em_queue_types.h:205
q_elem_atomic_group_::atomic_group
em_atomic_group_t atomic_group
Definition: em_queue_types.h:158
EM_MAX_OUTPUT_QUEUES
#define EM_MAX_OUTPUT_QUEUES
Definition: event_machine_config.h:131
internal_queue_t
Definition: em_queue_types.h:98
queue_state_e
enum queue_state queue_state_e
queue_tbl_t::output_queue_idx_free
bool output_queue_idx_free[EM_MAX_OUTPUT_QUEUES]
Definition: em_queue_types.h:279
queue_elem_t::qgrp_node
list_node_t qgrp_node
Definition: em_queue_types.h:257
queue_elem_t
Definition: em_queue_types.h:180
q_elem_output_::idx
uint32_t idx
Definition: em_queue_types.h:172
q_elem_output_t
struct q_elem_output_ q_elem_output_t
local_queues_t
struct local_queues_t local_queues_t