54#include "em_libconfig.h"
69COMPILE_TIME_ASSERT(
sizeof(_ev_hdr__size_check__arr_t) ==
78 EM_CHECK_LEVEL__BAD_VALUE);
80static int read_config_file(
void)
82 EM_PRINT(
"EM event vector config:\n");
84 const char *conf_str =
"vector.backend";
85 int ret = em_libconfig_lookup_string(&
em_shm->libconfig, conf_str,
88 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
92 const char *backend_str =
em_shm->
opt.vector.backend_str;
95 if (strcmp(backend_str,
"packet") == 0) {
96 em_shm->
opt.vector.backend = EM_VECTOR_BACKEND_PACKET;
97 }
else if (strcmp(backend_str,
"event") == 0) {
98 const odp_pool_capability_t *capa = &
em_shm->mpool_tbl.odp_pool_capability;
100 if (unlikely(capa->event_vector.max_pools == 0)) {
102 "Config option '%s = \"event\"' not supported by ODP\n",
106 em_shm->
opt.vector.backend = EM_VECTOR_BACKEND_EVENT;
109 "Invalid value '%s' for %s (expected \"packet\" or \"event\")\n",
110 backend_str, conf_str);
114 EM_PRINT(
" %s: %s\n", conf_str, backend_str);
121 if (read_config_file())
127void print_event_info(
void)
132 "event-hdr size: %zu B\n",
135 DBG_PRINT(
"\t\toffset\tsize\n"
137 "esv.state_cnt:\t%3zu B\t%2zu B\n"
138 "esv.state:\t%3zu B\t%2zu B\n"
139 "flags:\t\t%3zu B\t%2zu B\n"
140 "align_offset:\t%3zu B\t%2zu B\n"
141 "event_type:\t%3zu B\t%2zu B\n"
142 "event:\t\t%3zu B\t%2zu B\n"
143 "event_size:\t%3zu B\t%2zu B\n"
144 "egrp_gen:\t%3zu B\t%2zu B\n"
145 "egrp:\t\t%3zu B\t%2zu B\n"
146 "tmo:\t\t%3zu B\t%2zu B\n"
147 "user_area info:\t%3zu B\t%2zu B\n"
148 "vector_type:\t%3zu B\t%2zu B\n"
149 "end_hdr_data:\t%3zu B\t%2zu B\n"
151 "end:\t\t%3zu B\t%2zu B\n",
189 ev_hdr = event_alloc_pkt(pool_elem, size);
191 ev_hdr = event_alloc_buf(pool_elem, size);
193 ev_hdr = event_alloc_vector(pool_elem, size);
195 if (unlikely(ev_hdr == NULL))
201 em_event_t
event = ev_hdr->
event;
203 (void)evstate_prealloc(event, ev_hdr);
205 ev_hdr->
flags.all = 0;
218 return likely(list_node != NULL) ? ev_hdr : NULL;
230em_event_t pkt_clone_odp(odp_packet_t pkt, odp_pool_t pkt_pool,
231 uint32_t offset, uint32_t size,
232 bool clone_uarea,
bool is_clone_part)
234 odp_packet_t clone_pkt;
238 clone_pkt = odp_packet_copy_part(pkt, offset, size, pkt_pool);
239 if (unlikely(clone_pkt == ODP_PACKET_INVALID))
242 const void *src_odp_uarea = odp_packet_user_area(pkt);
243 void *dst_odp_uarea = odp_packet_user_area(clone_pkt);
248 uint32_t src_uarea_size = odp_packet_user_area_size(pkt);
249 uint32_t dst_uarea_size = odp_packet_user_area_size(clone_pkt);
251 if (unlikely(dst_uarea_size < src_uarea_size)) {
252 odp_packet_free(clone_pkt);
256 cpy_size = src_uarea_size;
259 memcpy(dst_odp_uarea, src_odp_uarea, cpy_size);
262 clone_pkt = odp_packet_copy(pkt, pkt_pool);
263 if (unlikely(clone_pkt == ODP_PACKET_INVALID))
269 odp_event_t odp_clone_event = odp_packet_to_event(clone_pkt);
270 event_hdr_t *clone_hdr = odp_packet_user_area(clone_pkt);
271 em_event_t clone_event = event_odp2em(odp_clone_event);
278 clone_event = evstate_init(clone_event, clone_hdr,
false);
280 clone_hdr->
event = clone_event;
282 clone_hdr->
flags.all = 0;
294 const uint32_t qidx = output_q_elem->output.
idx;
296 if (track->used_queues[qidx] == NULL) {
297 track->used_queues[qidx] = output_q_elem;
298 track->idx[track->idx_cnt++] = qidx;
305 const em_queue_t output_queue = (em_queue_t)(uintptr_t)output_q_elem->
queue;
308 void *
const output_fn_args =
311 const int deq_max = 32;
313 em_event_t output_ev_tbl[deq_max];
315 odp_event_t *
const odp_deq_events = (odp_event_t *)output_ev_tbl;
317 const odp_queue_t odp_queue = output_q_elem->
odp_queue;
318 unsigned int output_num;
322 const bool esv_ena = esv_enabled();
325 deq = odp_queue_deq_multi(odp_queue,
328 if (unlikely(deq <= 0))
331 output_num = (
unsigned int)deq;
337 event_to_hdr_multi(output_ev_tbl, ev_hdrs, output_num);
338 for (
unsigned int i = 0; i < output_num; i++)
340 output_ev_tbl[i] = ev_hdrs[i]->
event;
343 ret = output_fn(output_ev_tbl, output_num,
344 output_queue, output_fn_args);
346 if (unlikely((
unsigned int)ret != output_num))
352output_queue_buffering_drain(
void)
356 for (
unsigned int i = 0; i < track->idx_cnt; i++) {
357 int qidx = track->idx[i];
359 odp_ticketlock_t *lock = &output_q_elem->output.
lock;
365 if (odp_ticketlock_trylock(lock)) {
366 output_queue_drain(output_q_elem);
367 odp_ticketlock_unlock(lock);
371 track->used_queues[qidx] = NULL;
377uint32_t event_vector_tbl__odp_evvec(odp_event_vector_t evvec,
378 em_event_t **event_tbl )
380 odp_event_t *odp_evtbl = NULL;
381 uint32_t num = odp_event_vector_tbl(evvec, &odp_evtbl);
384 *event_tbl = (em_event_t *)odp_evtbl;
398 (void)events_em2odp_inplace(*event_tbl, num);
404 event_init_odp_multi(odp_evtbl , *event_tbl ,
405 ev_hdr_tbl , num,
false, NULL);
411uint32_t event_vector_tbl__odp_pktvec(odp_packet_vector_t pkt_vec,
412 em_event_t **event_tbl )
414 odp_packet_t *pkt_tbl = NULL;
415 uint32_t num = odp_packet_vector_tbl(pkt_vec, &pkt_tbl);
418 *event_tbl = (em_event_t *)pkt_tbl;
432 (void)events_em2pkt_inplace(*event_tbl, num);
438 event_init_pkt_multi(pkt_tbl , *event_tbl ,
439 ev_hdr_tbl , num,
false);
444uint32_t event_vector_tbl(em_event_t vector_event,
445 em_event_t **event_tbl )
447 odp_event_t odp_event = event_em2odp(vector_event);
448 odp_event_type_t odp_etype = odp_event_type(odp_event);
451 if (odp_etype == ODP_EVENT_VECTOR) {
452 odp_event_vector_t evvec = odp_event_vector_from_event(odp_event);
454 num = event_vector_tbl__odp_evvec(evvec, event_tbl );
457 odp_packet_vector_t pkt_vec = odp_packet_vector_from_event(odp_event);
459 num = event_vector_tbl__odp_pktvec(pkt_vec, event_tbl );
465em_status_t event_vector_max_size(em_event_t vector_event, uint32_t *max_size ,
468 odp_event_t odp_event = event_em2odp(vector_event);
469 odp_event_type_t odp_etype = odp_event_type(odp_event);
470 odp_pool_t odp_pool = ODP_POOL_INVALID;
472 if (odp_etype == ODP_EVENT_VECTOR) {
473 odp_event_vector_t evvec = odp_event_vector_from_event(odp_event);
475 odp_pool = odp_event_vector_pool(evvec);
478 odp_packet_vector_t pktvec = odp_packet_vector_from_event(odp_event);
480 odp_pool = odp_packet_vector_pool(pktvec);
484 em_pool_t pool = (em_pool_t)(uintptr_t)pool_subpool.pool;
485 int subpool = pool_subpool.subpool;
499 if (unlikely(!pool_elem ||
503 "Invalid pool:%" PRI_POOL "", pool);
510 "Subpool not found, pool:%" PRI_POOL "", pool);
514 *max_size = pool_elem->
size[subpool];
#define INTERNAL_ERROR(error, escope, fmt,...)
struct event_hdr event_hdr_t
ENV_LOCAL em_locm_t em_locm
#define EM_EVENT_GROUP_UNDEF
void em_free_multi(em_event_t events[], int num)
int(* em_output_func_t)(const em_event_t events[], const unsigned int num, const em_queue_t output_queue, void *output_fn_args)
output_queue_track_t output_queue_track
em_output_func_t output_fn
ev_hdr_user_area_t user_area
union event_hdr::@43 flags
em_event_type_t event_type
em_output_queue_conf_t output_conf