54#include "em_libconfig.h"
63static int read_config_file(
void);
69static const evstate_cnt_t init_cnt_alloc = {.evgen =
EVGEN_INIT,
77static const evstate_cnt_t init_cnt_extev = {.evgen =
EVGEN_INIT,
96 [EVSTATE__UNDEF] = {.str =
"undefined",
98 [EVSTATE__PREALLOC] = {.str =
"pool-create(prealloc-events)",
99 .escope = EM_ESCOPE_POOL_CREATE},
100 [EVSTATE__ALLOC] = {.str =
"em_alloc()",
101 .escope = EM_ESCOPE_ALLOC},
102 [EVSTATE__ALLOC_MULTI] = {.str =
"em_alloc_multi()",
103 .escope = EM_ESCOPE_ALLOC_MULTI},
104 [EVSTATE__EVENT_CLONE] = {.str =
"em_event_clone()",
105 .escope = EM_ESCOPE_EVENT_CLONE},
106 [EVSTATE__EVENT_REF] = {.str =
"em_event_ref()",
107 .escope = EM_ESCOPE_EVENT_REF},
108 [EVSTATE__FREE] = {.str =
"em_free()",
109 .escope = EM_ESCOPE_FREE},
110 [EVSTATE__FREE_MULTI] = {.str =
"em_free_multi()",
111 .escope = EM_ESCOPE_FREE_MULTI},
112 [EVSTATE__EVENT_VECTOR_FREE] = {.str =
"em_event_vector_free()",
113 .escope = EM_ESCOPE_EVENT_VECTOR_FREE},
114 [EVSTATE__INIT] = {.str =
"init-event",
116 [EVSTATE__INIT_MULTI] = {.str =
"init-events",
118 [EVSTATE__INIT_EXTEV] = {.str =
"dispatch(init-ext-event)",
119 .escope = EM_ESCOPE_DISPATCH},
120 [EVSTATE__INIT_EXTEV_MULTI] = {.str =
"dispatch(init-ext-events)",
121 .escope = EM_ESCOPE_DISPATCH},
122 [EVSTATE__UPDATE_EXTEV] = {.str =
"dispatch(update-ext-event)",
123 .escope = EM_ESCOPE_DISPATCH},
124 [EVSTATE__SEND] = {.str =
"em_send()",
125 .escope = EM_ESCOPE_SEND},
126 [EVSTATE__SEND__FAIL] = {.str =
"em_send(fail)",
127 .escope = EM_ESCOPE_SEND},
128 [EVSTATE__SEND_EGRP] = {.str =
"em_send_group()",
129 .escope = EM_ESCOPE_SEND_GROUP},
130 [EVSTATE__SEND_EGRP__FAIL] = {.str =
"em_send_group(fail)",
131 .escope = EM_ESCOPE_SEND_GROUP},
132 [EVSTATE__SEND_MULTI] = {.str =
"em_send_multi()",
133 .escope = EM_ESCOPE_SEND_MULTI},
134 [EVSTATE__SEND_MULTI__FAIL] = {.str =
"em_send_multi(fail)",
135 .escope = EM_ESCOPE_SEND_MULTI},
136 [EVSTATE__SEND_EGRP_MULTI] = {.str =
"em_send_group_multi()",
137 .escope = EM_ESCOPE_SEND_GROUP_MULTI},
138 [EVSTATE__SEND_EGRP_MULTI__FAIL] = {.str =
"em_send_group_multi(fail)",
139 .escope = EM_ESCOPE_SEND_GROUP_MULTI},
140 [EVSTATE__EO_START_SEND_BUFFERED] = {.str =
"eo-start:send-buffered-events()",
141 .escope = EM_ESCOPE_SEND_MULTI},
142 [EVSTATE__MARK_SEND] = {.str =
"em_event_mark_send()",
143 .escope = EM_ESCOPE_EVENT_MARK_SEND},
144 [EVSTATE__UNMARK_SEND] = {.str =
"em_event_unmark_send()",
145 .escope = EM_ESCOPE_EVENT_UNMARK_SEND},
146 [EVSTATE__MARK_FREE] = {.str =
"em_event_mark_free()",
147 .escope = EM_ESCOPE_EVENT_MARK_FREE},
148 [EVSTATE__UNMARK_FREE] = {.str =
"em_event_unmark_free()",
149 .escope = EM_ESCOPE_EVENT_UNMARK_FREE},
150 [EVSTATE__MARK_FREE_MULTI] = {.str =
"em_event_mark_free_multi()",
151 .escope = EM_ESCOPE_EVENT_MARK_FREE_MULTI},
152 [EVSTATE__UNMARK_FREE_MULTI] = {.str =
"em_event_unmark_free_multi()",
153 .escope = EM_ESCOPE_EVENT_UNMARK_FREE_MULTI},
154 [EVSTATE__DISPATCH] = {.str =
"em_dispatch(single-event)",
155 .escope = EM_ESCOPE_DISPATCH},
156 [EVSTATE__DISPATCH_MULTI] = {.str =
"em_dispatch(multiple-events)",
157 .escope = EM_ESCOPE_DISPATCH},
158 [EVSTATE__DISPATCH_AGGR] = {.str =
"em_dispatch(aggr-vec inner-event)",
159 .escope = EM_ESCOPE_DISPATCH},
160 [EVSTATE__DISPATCH_SCHED__FAIL] = {.str =
"em_dispatch(drop sched-events)",
161 .escope = EM_ESCOPE_DISPATCH},
162 [EVSTATE__DISPATCH_LOCAL__FAIL] = {.str =
"em_dispatch(drop local-events)",
163 .escope = EM_ESCOPE_DISPATCH},
164 [EVSTATE__DEQUEUE] = {.str =
"em_queue_dequeue()",
165 .escope = EM_ESCOPE_QUEUE_DEQUEUE},
166 [EVSTATE__DEQUEUE_MULTI] = {.str =
"em_queue_dequeue_multi()",
167 .escope = EM_ESCOPE_QUEUE_DEQUEUE_MULTI},
168 [EVSTATE__TMO_SET_ABS] = {.str =
"em_tmo_set_abs()",
169 .escope = EM_ESCOPE_TMO_SET_ABS},
170 [EVSTATE__TMO_SET_ABS__FAIL] = {.str =
"em_tmo_set_abs(fail)",
171 .escope = EM_ESCOPE_TMO_SET_ABS},
172 [EVSTATE__TMO_SET_REL] = {.str =
"em_tmo_set_rel()",
173 .escope = EM_ESCOPE_TMO_SET_REL},
174 [EVSTATE__TMO_SET_REL__FAIL] = {.str =
"em_tmo_set_rel(fail)",
175 .escope = EM_ESCOPE_TMO_SET_REL},
176 [EVSTATE__TMO_SET_PERIODIC] = {.str =
"em_tmo_set_periodic()",
177 .escope = EM_ESCOPE_TMO_SET_PERIODIC},
178 [EVSTATE__TMO_SET_PERIODIC__FAIL] = {.str =
"em_tmo_set_periodic(fail)",
179 .escope = EM_ESCOPE_TMO_SET_PERIODIC},
180 [EVSTATE__TMO_CANCEL] = {.str =
"em_tmo_cancel()",
181 .escope = EM_ESCOPE_TMO_CANCEL},
182 [EVSTATE__TMO_ACK] = {.str =
"em_tmo_ack()",
183 .escope = EM_ESCOPE_TMO_ACK},
184 [EVSTATE__TMO_ACK__NOSKIP] = {.str =
"em_tmo_ack(noskip)",
185 .escope = EM_ESCOPE_TMO_ACK},
186 [EVSTATE__TMO_ACK__FAIL] = {.str =
"em_tmo_ack(fail)",
187 .escope = EM_ESCOPE_TMO_ACK},
188 [EVSTATE__TMO_CREATE] = {.str =
"em_tmo_create()",
189 .escope = EM_ESCOPE_TMO_CREATE},
190 [EVSTATE__TMO_DELETE] = {.str =
"em_tmo_delete()",
191 .escope = EM_ESCOPE_TMO_DELETE},
192 [EVSTATE__AG_DELETE] = {.str =
"em_atomic_group_delete(flush)",
193 .escope = EM_ESCOPE_ATOMIC_GROUP_DELETE},
194 [EVSTATE__TERM_CORE__QUEUE_LOCAL] = {.str =
"em_term_core(local-queue)",
195 .escope = EM_ESCOPE_TERM_CORE},
196 [EVSTATE__TERM] = {.str =
"em_term()",
197 .escope = EM_ESCOPE_TERM},
199 [EVSTATE__LAST] = {.str =
"last",
203static const char *
const help_str_em2usr =
204"OK: 'send < ref, both >=0'. Err otherwise";
205static const char *
const help_str_usr2em =
206"OK: 'send <= ref, both >=0' AND 'hdl evgen == evgen'. Err otherwise";
207static const char *
const help_str_usr2em_ref =
208"OK: 'send <= ref, both >=0'. Err otherwise";
211esv_update_state(
ev_hdr_state_t *
const evstate,
const uint16_t api_op,
212 const void *
const ev_ptr)
215 const uint32_t *
const pl_u32 = ev_ptr;
225 evstate->
eo_idx = (int16_t)eo_hdl2idx((em_eo_t)(uintptr_t)q_elem->
eo);
226 evstate->
queue_idx = (int16_t)queue_hdl2idx((em_queue_t)(uintptr_t)q_elem->
queue);
228 evstate->
api_op = (uint8_t)api_op;
233evhdr_update_state(
event_hdr_t *
const ev_hdr,
const uint16_t api_op)
238 const void *ev_ptr = NULL;
241 ev_ptr = event_pointer(ev_hdr->
event);
243 esv_update_state(&ev_hdr->
state, api_op, ev_ptr);
247#define EVSTATE_ERROR_FMT \
248"ESV: Event:%" PRI_EVENT " state error -- counts:\t" \
249"send:%" PRIi16 " ref:%" PRIi16 " evgen:%" PRIu16 "(%" PRIu16 ")\n" \
251" prev-state:%s core:%02u:\t" \
252" EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
253"=> err-state:%s core:%02u:\t" \
254" EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
255" event:0x%016" PRIx64 ": ptr:0x%" PRIx64 ""
258#define EVSTATE_REF_ERROR_FMT \
259"ESV: RefEvent:%" PRI_EVENT " state error -- counts:\t" \
260"send:%" PRIi16 " ref:%" PRIi16 " (evgen:%" PRIu16 " ignored for refs)\n" \
262" prev-state:n/a (not valid for event references)\n" \
263"=> err-state:%s core:%02u:\t" \
264" EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
265" event:0x%016" PRIx64 ": ptr:0x%" PRIx64 ""
268#define EVSTATE_UNMARK_ERROR_FMT \
269"ESV: Event:%" PRI_EVENT " state error - Invalid 'unmark'-API use\n"\
270" prev-state:%s core:%02u:\t" \
271" EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
272"=> err-state:%s core:%02u:\t" \
273" EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n"
276#define EVSTATE__NO_PREV_STATE__ERROR_FMT \
277"ESV: Event:%" PRI_EVENT " state error -- counts:\t" \
278"send:%" PRIi16 " ref:%" PRIi16 " evgen:%" PRIu16 "(%" PRIu16 ")\n" \
280" prev-state:n/a (disabled in conf)\n" \
281"=> err-state:%s core:%02u:\t" \
282" EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
283" event:0x%016" PRIx64 ": ptr:0x%" PRIx64 ""
286#define EVSTATE__NO_PREV_STATE__UNMARK_ERROR_FMT \
287"ESV: Event:%" PRI_EVENT " state error - Invalid 'unmark'-API use\n"\
288" prev-state:n/a (disabled in conf)\n" \
289"=> err-state:%s core:%02u:\t" \
290" EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n"
296esv_error(
const evstate_cnt_t cnt,
298 const uint16_t api_op,
bool is_unmark_error,
299 const char *
const help_str)
304 const em_event_t
event = event_hdr_to_event(ev_hdr);
305 const void *ev_ptr = NULL;
307 if (unlikely(prev_op > EVSTATE__LAST))
308 prev_op = EVSTATE__UNDEF;
317 char curr_payload[
sizeof(
"0x12345678 ")] =
"(n/a)";
318 char prev_payload[
sizeof(
"0x12345678 ")] =
"(n/a)";
325 ev_ptr = event_pointer(event);
327 esv_update_state(&err_state, api_op, ev_ptr);
335 snprintf(curr_payload,
sizeof(curr_payload),
337 curr_payload[
sizeof(curr_payload) - 1] =
'\0';
340 em_eo_t curr_eo = eo_idx2hdl(err_state.
eo_idx);
341 em_queue_t curr_queue = queue_idx2hdl(err_state.
queue_idx);
344 eo_elem = eo_elem_get(curr_eo);
346 eo_name(eo_elem, curr_eoname,
sizeof(curr_eoname));
348 q_elem = queue_elem_get(curr_queue);
350 queue_name(q_elem, curr_qname,
sizeof(curr_qname));
354 const uint16_t evgen_hdl = evhdl.evgen -
EVGEN_INIT;
365 snprintf(prev_payload,
sizeof(prev_payload),
367 prev_payload[
sizeof(prev_payload) - 1] =
'\0';
370 em_eo_t prev_eo = eo_idx2hdl(prev_state.
eo_idx);
371 em_queue_t prev_queue = queue_idx2hdl(prev_state.
queue_idx);
374 eo_elem = eo_elem_get(prev_eo);
376 eo_name(eo_elem, prev_eoname,
sizeof(prev_eoname));
378 q_elem = queue_elem_get(prev_queue);
380 queue_name(q_elem, prev_qname,
sizeof(prev_qname));
385 err_info->escope, EVSTATE_REF_ERROR_FMT,
386 event, send_cnt, ref_cnt, evgen_cnt, help_str,
387 err_info->str, err_state.
core,
388 curr_eo, curr_eoname, curr_queue, curr_qname,
389 curr_payload, evhdl.event, evhdl.evptr);
390 }
else if (!is_unmark_error) {
393 err_info->escope, EVSTATE_ERROR_FMT,
394 event, send_cnt, ref_cnt, evgen_hdl, evgen_cnt, help_str,
395 prev_info->str, prev_state.
core, prev_eo, prev_eoname,
396 prev_queue, prev_qname, prev_payload,
397 err_info->str, err_state.
core, curr_eo, curr_eoname,
398 curr_queue, curr_qname, curr_payload,
399 evhdl.event, evhdl.evptr);
406 err_info->escope, EVSTATE_UNMARK_ERROR_FMT,
408 prev_info->str, prev_state.
core,
409 prev_eo, prev_eoname,
410 prev_queue, prev_qname, prev_payload,
411 err_info->str, err_state.
core,
412 curr_eo, curr_eoname,
413 curr_queue, curr_qname, curr_payload);
417 if (!is_unmark_error) {
420 err_info->escope, EVSTATE__NO_PREV_STATE__ERROR_FMT,
421 event, send_cnt, ref_cnt, evgen_hdl, evgen_cnt, help_str,
422 err_info->str, err_state.
core, curr_eo, curr_eoname,
423 curr_queue, curr_qname, curr_payload,
424 evhdl.event, evhdl.evptr);
431 err_info->escope, EVSTATE__NO_PREV_STATE__UNMARK_ERROR_FMT,
433 err_info->str, err_state.
core, curr_eo, curr_eoname,
434 curr_queue, curr_qname, curr_payload);
440evstate_error(
const evstate_cnt_t cnt,
evhdl_t evhdl,
441 const event_hdr_t *
const ev_hdr,
const uint16_t api_op,
442 const char *
const help_str)
445 esv_error(cnt, evhdl, ev_hdr, api_op,
false, help_str);
452evstate_unmark_error(
const event_hdr_t *
const ev_hdr,
const uint16_t api_op)
454 evstate_cnt_t dont_care = {.u64 = 0};
458 esv_error(dont_care, dont_care_hdl, ev_hdr, api_op,
true,
"n/a");
461static inline em_event_t
462esv_evinit(
const em_event_t event,
event_hdr_t *
const ev_hdr,
463 const evstate_cnt_t init_cnt,
const uint16_t api_op)
465 evhdl_t evhdl = {.event =
event};
468 ev_hdr->
event = evhdl.event;
471 __atomic_store_n(&ev_hdr->
state_cnt.u64, init_cnt.u64,
474 evhdr_update_state(ev_hdr, api_op);
480esv_evinit_multi(em_event_t ev_tbl[],
482 const evstate_cnt_t init_cnt,
const uint16_t api_op)
486 for (
int i = 0; i < num; i++) {
488 ev_hdr_tbl[i]->
event = evhdl_tbl[i].event;
491 __atomic_store_n(&ev_hdr_tbl[i]->state_cnt.u64,
492 init_cnt.u64, __ATOMIC_RELAXED);
494 evhdr_update_state(ev_hdr_tbl[i], api_op);
498static inline em_event_t
499esv_evinit_ext(
const em_event_t event,
event_hdr_t *
const ev_hdr,
500 const uint16_t api_op)
507 evhdl_t evhdl = {.event =
event};
508 const evstate_cnt_t init = init_cnt_extev;
509 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
510 .ref_cnt = 0, .send_cnt = 1};
511 const evstate_cnt_t cnt = {.u64 = init.u64 - sub.u64};
513 evhdl.evgen = cnt.evgen;
514 ev_hdr->
event = evhdl.event;
517 __atomic_store_n(&ev_hdr->
state_cnt.u64, cnt.u64,
521 evhdr_update_state(ev_hdr, api_op);
526static inline em_event_t
527esv_em2usr(
const em_event_t event,
event_hdr_t *
const ev_hdr,
528 const evstate_cnt_t cnt,
const uint16_t api_op,
const bool is_revert)
531 evhdl_t evhdl = {.event =
event};
532 evstate_cnt_t new_cnt;
535 if (unlikely(is_revert)) {
537 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
538 cnt.u64, __ATOMIC_RELAXED);
541 new_cnt.u64 = __atomic_sub_fetch(&ev_hdr->
state_cnt.u64,
542 cnt.u64, __ATOMIC_RELAXED);
546 evhdl.evgen = new_cnt.evgen;
547 ev_hdr->
event = evhdl.event;
557 if (unlikely(send_cnt >= ref_cnt || send_cnt < 0)) {
559 evstate_error(new_cnt, evhdl, ev_hdr, api_op, help_str_em2usr);
567 evhdr_update_state(ev_hdr, api_op);
573esv_em2usr_multi(em_event_t ev_tbl[],
575 const evstate_cnt_t cnt,
const uint16_t api_op,
576 const bool is_revert)
579 evstate_cnt_t new_cnt;
581 for (
int i = 0; i < num; i++) {
588 if (unlikely(is_revert)) {
591 __atomic_add_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
592 cnt.u64, __ATOMIC_RELAXED);
596 __atomic_sub_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
597 cnt.u64, __ATOMIC_RELAXED);
601 evhdl_tbl[i].evgen = new_cnt.evgen;
602 ev_hdr_tbl[i]->
event = evhdl_tbl[i].event;
612 if (unlikely(send_cnt >= ref_cnt || send_cnt < 0)) {
614 evstate_error(new_cnt, evhdl_tbl[i], ev_hdr_tbl[i],
615 api_op, help_str_em2usr);
623 evhdr_update_state(ev_hdr_tbl[i], api_op);
628esv_usr2em(
const em_event_t event,
event_hdr_t *
const ev_hdr,
629 const evstate_cnt_t cnt,
const uint16_t api_op,
const bool is_revert)
632 evhdl_t evhdl = {.event =
event};
633 evstate_cnt_t new_cnt;
636 if (unlikely(is_revert)) {
638 new_cnt.u64 = __atomic_sub_fetch(&ev_hdr->
state_cnt.u64,
639 cnt.u64, __ATOMIC_RELAXED);
641 if (unlikely(new_cnt.evgen ==
EVGEN_INIT - 1)) {
644 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
645 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
646 add.u64, __ATOMIC_RELAXED);
650 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
651 cnt.u64, __ATOMIC_RELAXED);
653 if (unlikely(new_cnt.evgen ==
EVGEN_MAX)) {
656 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
657 __atomic_fetch_sub(&ev_hdr->
state_cnt.u64, sub.u64,
678 if (unlikely((send_cnt > ref_cnt || send_cnt < 0) ||
679 (!refs_used && evhdl.evgen != new_cnt.evgen))) {
680 const char *
const help_str = refs_used ? help_str_usr2em_ref : help_str_usr2em;
683 evstate_error(new_cnt, evhdl, ev_hdr, api_op, help_str);
691 evhdr_update_state(ev_hdr, api_op);
695esv_usr2em_multi(
const em_event_t ev_tbl[],
697 const evstate_cnt_t cnt,
const uint16_t api_op,
698 const bool is_revert)
701 evstate_cnt_t new_cnt;
703 for (
int i = 0; i < num; i++) {
710 if (unlikely(is_revert)) {
713 __atomic_sub_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
714 cnt.u64, __ATOMIC_RELAXED);
716 if (unlikely(new_cnt.evgen ==
EVGEN_INIT - 1)) {
719 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
721 __atomic_add_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
722 add.u64, __ATOMIC_RELAXED);
727 __atomic_add_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
728 cnt.u64, __ATOMIC_RELAXED);
730 if (unlikely(new_cnt.evgen ==
EVGEN_MAX)) {
733 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
734 __atomic_fetch_sub(&ev_hdr_tbl[i]->state_cnt.u64, sub.u64,
755 if (unlikely((send_cnt > ref_cnt || send_cnt < 0) ||
756 (!refs_used && evhdl_tbl[i].evgen != new_cnt.evgen))) {
758 evstate_error(new_cnt, evhdl_tbl[i], ev_hdr_tbl[i],
759 api_op, help_str_usr2em);
767 evhdr_update_state(ev_hdr_tbl[i], api_op);
771em_event_t evstate_prealloc(
const em_event_t event,
event_hdr_t *
const ev_hdr)
773 return esv_evinit(event, ev_hdr, init_cnt_alloc, EVSTATE__PREALLOC);
776em_event_t evstate_alloc(
const em_event_t event,
event_hdr_t *
const ev_hdr,
777 const uint16_t api_op)
780 return esv_evinit(event, ev_hdr, init_cnt_alloc, api_op);
782 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
783 .ref_cnt = 1, .send_cnt = 0};
785 return esv_em2usr(event, ev_hdr, sub, api_op,
false);
788em_event_t evstate_alloc_tmo(
const em_event_t event,
event_hdr_t *
const ev_hdr)
790 return esv_evinit(event, ev_hdr, init_cnt_alloc, EVSTATE__TMO_CREATE);
793void evstate_alloc_multi(em_event_t ev_tbl[],
797 esv_evinit_multi(ev_tbl, ev_hdr_tbl, num,
798 init_cnt_alloc, EVSTATE__ALLOC_MULTI);
803 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
804 .ref_cnt = 1, .send_cnt = 0};
806 for (
int i = 0; i < num; i++) {
808 ev_tbl[i] = esv_evinit(ev_tbl[i], ev_hdr_tbl[i],
810 EVSTATE__ALLOC_MULTI);
812 ev_tbl[i] = esv_em2usr(ev_tbl[i], ev_hdr_tbl[i], sub,
813 EVSTATE__ALLOC_MULTI,
false);
818em_event_t evstate_ref(
const em_event_t event,
event_hdr_t *
const ev_hdr)
820 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
821 .ref_cnt = 1, .send_cnt = 0};
823 return esv_em2usr(event, ev_hdr, sub, EVSTATE__EVENT_REF,
false);
826em_event_t evstate_init(
const em_event_t event,
event_hdr_t *
const ev_hdr,
830 return esv_evinit_ext(event, ev_hdr, EVSTATE__INIT_EXTEV);
832 return esv_evinit(event, ev_hdr, init_cnt_alloc, EVSTATE__INIT);
835void evstate_init_multi(em_event_t ev_tbl[],
840 evstate_cnt_t init_cnt;
843 api_op = EVSTATE__INIT_EXTEV_MULTI;
844 init_cnt = init_cnt_extev;
846 api_op = EVSTATE__INIT_MULTI;
847 init_cnt = init_cnt_alloc;
850 esv_evinit_multi(ev_tbl, ev_hdr_tbl, num,
880static inline em_event_t
881esv_update_ext(
const em_event_t event,
event_hdr_t *
const ev_hdr,
882 const uint16_t api_op)
884 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
885 .ref_cnt = 1, .send_cnt = 0};
886 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
887 .ref_cnt = 0, .send_cnt = 0};
888 const evstate_cnt_t cmb = {.u64 = add.u64 - sub.u64};
891 evhdl_t evhdl = {.event =
event};
892 evstate_cnt_t new_cnt;
895 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
896 cmb.u64, __ATOMIC_RELAXED);
898 if (unlikely(new_cnt.evgen ==
EVGEN_MAX)) {
901 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
902 new_cnt.u64 = __atomic_sub_fetch(&ev_hdr->
state_cnt.u64, wrap.u64,
907 evhdl.evgen = new_cnt.evgen;
908 ev_hdr->
event = evhdl.event;
918 if (unlikely(send_cnt >= ref_cnt || send_cnt < 0)) {
920 evstate_error(new_cnt, evhdl, ev_hdr, api_op, help_str_em2usr);
928 evhdr_update_state(ev_hdr, api_op);
933em_event_t evstate_update(
const em_event_t event,
event_hdr_t *
const ev_hdr,
936 em_event_t ret_event;
940 ret_event = esv_update_ext(event, ev_hdr, EVSTATE__UPDATE_EXTEV);
943 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
944 .ref_cnt = 1, .send_cnt = 0};
946 ret_event = esv_em2usr(event, ev_hdr, sub, EVSTATE__UPDATE_EXTEV,
false);
952void evstate_free(
const em_event_t event,
event_hdr_t *
const ev_hdr,
953 const uint16_t api_op)
955 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
956 .ref_cnt = 1, .send_cnt = 0};
958 esv_usr2em(event, ev_hdr, add, api_op,
false);
961void evstate_free_revert(
const em_event_t event,
event_hdr_t *
const ev_hdr,
962 const uint16_t api_op)
964 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
965 .ref_cnt = 1, .send_cnt = 0};
967 esv_usr2em(event, ev_hdr, sub, api_op,
true );
970void evstate_free_multi(
const em_event_t ev_tbl[],
972 const uint16_t api_op)
974 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
975 .ref_cnt = 1, .send_cnt = 0};
977 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, add, api_op,
false);
980void evstate_free_revert_multi(
const em_event_t ev_tbl[],
982 const uint16_t api_op)
984 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
985 .ref_cnt = 1, .send_cnt = 0};
987 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, sub, api_op,
true );
990em_event_t evstate_em2usr(
const em_event_t event,
event_hdr_t *
const ev_hdr,
991 const uint16_t api_op)
996 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
997 .ref_cnt = 0, .send_cnt = 1};
999 return esv_em2usr(event, ev_hdr, sub, api_op,
false);
1002em_event_t evstate_em2usr_revert(
const em_event_t event,
event_hdr_t *
const ev_hdr,
1003 const uint16_t api_op)
1008 const evstate_cnt_t add = {.evgen = 0, .rsvd = 0,
1009 .ref_cnt = 0, .send_cnt = 1};
1011 return esv_em2usr(event, ev_hdr, add, api_op,
true );
1014void evstate_em2usr_multi(em_event_t ev_tbl[],
1016 const uint16_t api_op)
1018 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
1019 .ref_cnt = 0, .send_cnt = 1};
1021 esv_em2usr_multi(ev_tbl, ev_hdr_tbl, num, sub, api_op,
false);
1024void evstate_em2usr_revert_multi(em_event_t ev_tbl[],
1026 const uint16_t api_op)
1028 const evstate_cnt_t add = {.evgen = 0, .rsvd = 0,
1029 .ref_cnt = 0, .send_cnt = 1};
1031 esv_em2usr_multi(ev_tbl, ev_hdr_tbl, num, add, api_op,
true );
1035 const uint16_t api_op)
1040 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
1041 .ref_cnt = 0, .send_cnt = 1};
1043 esv_usr2em(event, ev_hdr, add, api_op,
false);
1046void evstate_usr2em_revert(
const em_event_t event,
event_hdr_t *
const ev_hdr,
1047 const uint16_t api_op)
1052 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
1053 .ref_cnt = 0, .send_cnt = 1};
1055 esv_usr2em(event, ev_hdr, sub, api_op,
true );
1058void evstate_usr2em_multi(
const em_event_t ev_tbl[],
1060 const uint16_t api_op)
1062 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
1063 .ref_cnt = 0, .send_cnt = 1};
1065 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, add, api_op,
false);
1068void evstate_usr2em_revert_multi(
const em_event_t ev_tbl[],
1070 const uint16_t api_op)
1072 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
1073 .ref_cnt = 0, .send_cnt = 1};
1075 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, sub, api_op,
true );
1083check_valid_unmark(
const event_hdr_t *ev_hdr, uint16_t api_op,
1084 const uint16_t expected_ops[],
const int num_ops)
1092 for (
int i = 0; i < num_ops; i++) {
1093 if (prev_op == expected_ops[i])
1098 evstate_unmark_error(ev_hdr, api_op);
1102check_valid_unmark_multi(
event_hdr_t *
const ev_hdr_tbl[],
const int num_evs,
1103 uint16_t api_op,
const uint16_t expected_ops[],
const int num_ops)
1108 for (
int i = 0; i < num_evs; i++) {
1110 if (ev_hdr_tbl[i]->flags.refs_used)
1116 for (
int j = 0; j < num_ops; j++) {
1117 if (prev_op == expected_ops[j]) {
1124 if (unlikely(!is_valid))
1125 evstate_unmark_error(ev_hdr_tbl[i], api_op);
1129void evstate_unmark_send(
const em_event_t event,
event_hdr_t *
const ev_hdr)
1132 uint16_t expected_prev_ops[1] = {EVSTATE__MARK_SEND};
1137 check_valid_unmark(ev_hdr, EVSTATE__UNMARK_SEND,
1138 expected_prev_ops, 1);
1141 evstate_usr2em_revert(event, ev_hdr, EVSTATE__UNMARK_SEND);
1144void evstate_unmark_free(
const em_event_t event,
event_hdr_t *
const ev_hdr,
1145 const uint16_t api_op)
1148 uint16_t expected_prev_ops[2] = {EVSTATE__MARK_FREE,
1149 EVSTATE__MARK_FREE_MULTI};
1154 check_valid_unmark(ev_hdr, api_op, expected_prev_ops, 2);
1157 evstate_free_revert(event, ev_hdr, api_op);
1160void evstate_unmark_free_multi(
const em_event_t ev_tbl[],
1162 const uint16_t api_op)
1165 uint16_t expected_prev_ops[2] = {EVSTATE__MARK_FREE_MULTI,
1166 EVSTATE__MARK_FREE};
1172 check_valid_unmark_multi(ev_hdr_tbl, num, api_op,
1173 expected_prev_ops, 2);
1176 evstate_free_revert_multi(ev_tbl, ev_hdr_tbl, num, api_op);
1179static int read_config_file(
void)
1181 const char *conf_str;
1182 bool val_bool =
false;
1185 EM_PRINT(
"EM ESV config:\n");
1188 EM_PRINT(
" ESV is DISABLED (build time)\n");
1197 conf_str =
"esv.enable";
1198 ret = em_libconfig_lookup_bool(&
em_shm->libconfig, conf_str, &val_bool);
1199 if (unlikely(!ret)) {
1200 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1206 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false", val_bool);
1217 conf_str =
"esv.store_state";
1218 ret = em_libconfig_lookup_bool(&
em_shm->libconfig, conf_str, &val_bool);
1219 if (unlikely(!ret)) {
1220 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1224 em_shm->
opt.esv.store_state = (int)val_bool;
1225 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
1231 conf_str =
"esv.store_payload_first_u32";
1232 ret = em_libconfig_lookup_bool(&
em_shm->libconfig, conf_str, &val_bool);
1233 if (unlikely(!ret)) {
1234 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1238 em_shm->
opt.esv.store_first_u32 = (int)val_bool;
1239 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
1245 conf_str =
"esv.prealloc_pools";
1246 ret = em_libconfig_lookup_bool(&
em_shm->libconfig, conf_str, &val_bool);
1247 if (unlikely(!ret)) {
1248 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1252 em_shm->
opt.esv.prealloc_pools = (int)val_bool;
1253 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
1261 if (read_config_file())
#define INTERNAL_ERROR(error, escope, fmt,...)
ENV_LOCAL em_locm_t em_locm
#define EM_QUEUE_NAME_LEN
#define EM_ESCOPE_INTERNAL_MASK
#define EM_ESCOPE_ODP_EXT
em_locm_current_t current
union event_hdr::@43 flags
em_event_type_t event_type