33 static int read_config_file(
void);
39 static const evstate_cnt_t init_cnt_alloc = {.evgen =
EVGEN_INIT,
47 static const evstate_cnt_t init_cnt_extev = {.evgen =
EVGEN_INIT,
66 [EVSTATE__UNDEF] = {.str =
"undefined",
68 [EVSTATE__PREALLOC] = {.str =
"pool-create(prealloc-events)",
70 [EVSTATE__ALLOC] = {.str =
"em_alloc()",
71 .escope = EM_ESCOPE_ALLOC},
72 [EVSTATE__ALLOC_MULTI] = {.str =
"em_alloc_multi()",
73 .escope = EM_ESCOPE_ALLOC_MULTI},
74 [EVSTATE__EVENT_CLONE] = {.str =
"em_event_clone()",
75 .escope = EM_ESCOPE_EVENT_CLONE},
76 [EVSTATE__EVENT_REF] = {.str =
"em_event_ref()",
77 .escope = EM_ESCOPE_EVENT_REF},
78 [EVSTATE__FREE] = {.str =
"em_free()",
79 .escope = EM_ESCOPE_FREE},
80 [EVSTATE__FREE_MULTI] = {.str =
"em_free_multi()",
81 .escope = EM_ESCOPE_FREE_MULTI},
82 [EVSTATE__EVENT_VECTOR_FREE] = {.str =
"em_event_vector_free()",
83 .escope = EM_ESCOPE_EVENT_VECTOR_FREE},
84 [EVSTATE__INIT] = {.str =
"init-event",
86 [EVSTATE__INIT_MULTI] = {.str =
"init-events",
88 [EVSTATE__INIT_EXTEV] = {.str =
"dispatch(init-ext-event)",
89 .escope = EM_ESCOPE_DISPATCH},
90 [EVSTATE__INIT_EXTEV_MULTI] = {.str =
"dispatch(init-ext-events)",
91 .escope = EM_ESCOPE_DISPATCH},
92 [EVSTATE__UPDATE_EXTEV] = {.str =
"dispatch(update-ext-event)",
93 .escope = EM_ESCOPE_DISPATCH},
94 [EVSTATE__SEND] = {.str =
"em_send()",
95 .escope = EM_ESCOPE_SEND},
96 [EVSTATE__SEND__FAIL] = {.str =
"em_send(fail)",
97 .escope = EM_ESCOPE_SEND},
98 [EVSTATE__SEND_EGRP] = {.str =
"em_send_group()",
99 .escope = EM_ESCOPE_SEND_GROUP},
100 [EVSTATE__SEND_EGRP__FAIL] = {.str =
"em_send_group(fail)",
101 .escope = EM_ESCOPE_SEND_GROUP},
102 [EVSTATE__SEND_MULTI] = {.str =
"em_send_multi()",
103 .escope = EM_ESCOPE_SEND_MULTI},
104 [EVSTATE__SEND_MULTI__FAIL] = {.str =
"em_send_multi(fail)",
105 .escope = EM_ESCOPE_SEND_MULTI},
106 [EVSTATE__SEND_EGRP_MULTI] = {.str =
"em_send_group_multi()",
107 .escope = EM_ESCOPE_SEND_GROUP_MULTI},
108 [EVSTATE__SEND_EGRP_MULTI__FAIL] = {.str =
"em_send_group_multi(fail)",
109 .escope = EM_ESCOPE_SEND_GROUP_MULTI},
110 [EVSTATE__EO_START_SEND_BUFFERED] = {.str =
"eo-start:send-buffered-events()",
111 .escope = EM_ESCOPE_SEND_MULTI},
112 [EVSTATE__MARK_SEND] = {.str =
"em_event_mark_send()",
113 .escope = EM_ESCOPE_EVENT_MARK_SEND},
114 [EVSTATE__UNMARK_SEND] = {.str =
"em_event_unmark_send()",
115 .escope = EM_ESCOPE_EVENT_UNMARK_SEND},
116 [EVSTATE__MARK_FREE] = {.str =
"em_event_mark_free()",
117 .escope = EM_ESCOPE_EVENT_MARK_FREE},
118 [EVSTATE__UNMARK_FREE] = {.str =
"em_event_unmark_free()",
119 .escope = EM_ESCOPE_EVENT_UNMARK_FREE},
120 [EVSTATE__MARK_FREE_MULTI] = {.str =
"em_event_mark_free_multi()",
121 .escope = EM_ESCOPE_EVENT_MARK_FREE_MULTI},
122 [EVSTATE__UNMARK_FREE_MULTI] = {.str =
"em_event_unmark_free_multi()",
123 .escope = EM_ESCOPE_EVENT_UNMARK_FREE_MULTI},
124 [EVSTATE__DISPATCH] = {.str =
"em_dispatch(single-event)",
125 .escope = EM_ESCOPE_DISPATCH},
126 [EVSTATE__DISPATCH_MULTI] = {.str =
"em_dispatch(multiple-events)",
127 .escope = EM_ESCOPE_DISPATCH},
128 [EVSTATE__DISPATCH_SCHED__FAIL] = {.str =
"em_dispatch(drop sched-events)",
129 .escope = EM_ESCOPE_DISPATCH},
130 [EVSTATE__DISPATCH_LOCAL__FAIL] = {.str =
"em_dispatch(drop local-events)",
131 .escope = EM_ESCOPE_DISPATCH},
132 [EVSTATE__DEQUEUE] = {.str =
"em_queue_dequeue()",
133 .escope = EM_ESCOPE_QUEUE_DEQUEUE},
134 [EVSTATE__DEQUEUE_MULTI] = {.str =
"em_queue_dequeue_multi()",
135 .escope = EM_ESCOPE_QUEUE_DEQUEUE_MULTI},
136 [EVSTATE__TMO_SET_ABS] = {.str =
"em_tmo_set_abs()",
137 .escope = EM_ESCOPE_TMO_SET_ABS},
138 [EVSTATE__TMO_SET_ABS__FAIL] = {.str =
"em_tmo_set_abs(fail)",
139 .escope = EM_ESCOPE_TMO_SET_ABS},
140 [EVSTATE__TMO_SET_REL] = {.str =
"em_tmo_set_rel()",
141 .escope = EM_ESCOPE_TMO_SET_REL},
142 [EVSTATE__TMO_SET_REL__FAIL] = {.str =
"em_tmo_set_rel(fail)",
143 .escope = EM_ESCOPE_TMO_SET_REL},
144 [EVSTATE__TMO_SET_PERIODIC] = {.str =
"em_tmo_set_periodic()",
145 .escope = EM_ESCOPE_TMO_SET_PERIODIC},
146 [EVSTATE__TMO_SET_PERIODIC__FAIL] = {.str =
"em_tmo_set_periodic(fail)",
147 .escope = EM_ESCOPE_TMO_SET_PERIODIC},
148 [EVSTATE__TMO_CANCEL] = {.str =
"em_tmo_cancel()",
149 .escope = EM_ESCOPE_TMO_CANCEL},
150 [EVSTATE__TMO_ACK] = {.str =
"em_tmo_ack()",
151 .escope = EM_ESCOPE_TMO_ACK},
152 [EVSTATE__TMO_ACK__NOSKIP] = {.str =
"em_tmo_ack(noskip)",
153 .escope = EM_ESCOPE_TMO_ACK},
154 [EVSTATE__TMO_ACK__FAIL] = {.str =
"em_tmo_ack(fail)",
155 .escope = EM_ESCOPE_TMO_ACK},
156 [EVSTATE__TMO_CREATE] = {.str =
"em_tmo_create()",
157 .escope = EM_ESCOPE_TMO_CREATE},
158 [EVSTATE__TMO_DELETE] = {.str =
"em_tmo_delete()",
159 .escope = EM_ESCOPE_TMO_DELETE},
160 [EVSTATE__AG_DELETE] = {.str =
"em_atomic_group_delete(flush)",
161 .escope = EM_ESCOPE_ATOMIC_GROUP_DELETE},
162 [EVSTATE__TERM_CORE__QUEUE_LOCAL] = {.str =
"em_term_core(local-queue)",
164 [EVSTATE__TERM] = {.str =
"em_term()",
167 [EVSTATE__LAST] = {.str =
"last",
171 static const char *
const help_str_em2usr =
172 "OK: 'send < ref, both >=0'. Err otherwise";
173 static const char *
const help_str_usr2em =
174 "OK: 'send <= ref, both >=0' AND 'hdl evgen == evgen'. Err otherwise";
175 static const char *
const help_str_usr2em_ref =
176 "OK: 'send <= ref, both >=0'. Err otherwise";
179 esv_update_state(
ev_hdr_state_t *
const evstate,
const uint16_t api_op,
180 const void *
const ev_ptr)
183 const uint32_t *
const pl_u32 = ev_ptr;
193 evstate->
eo_idx = (int16_t)eo_hdl2idx((em_eo_t)(uintptr_t)q_elem->
eo);
194 evstate->
queue_idx = (int16_t)queue_hdl2idx((em_queue_t)(uintptr_t)q_elem->
queue);
196 evstate->
api_op = (uint8_t)api_op;
201 evhdr_update_state(
event_hdr_t *
const ev_hdr,
const uint16_t api_op)
203 if (!
em_shm->opt.esv.store_state)
206 const void *ev_ptr = NULL;
208 if (
em_shm->opt.esv.store_first_u32)
209 ev_ptr = event_pointer(ev_hdr->
event);
211 esv_update_state(&ev_hdr->
state, api_op, ev_ptr);
215 #define EVSTATE_ERROR_FMT \
216 "ESV: Event:%" PRI_EVENT " state error -- counts:\t" \
217 "send:%" PRIi16 " ref:%" PRIi16 " evgen:%" PRIu16 "(%" PRIu16 ")\n" \
219 " prev-state:%s core:%02u:\t" \
220 " EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
221 "=> err-state:%s core:%02u:\t" \
222 " EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
223 " event:0x%016" PRIx64 ": ptr:0x%" PRIx64 ""
226 #define EVSTATE_REF_ERROR_FMT \
227 "ESV: RefEvent:%" PRI_EVENT " state error -- counts:\t" \
228 "send:%" PRIi16 " ref:%" PRIi16 " (evgen:%" PRIu16 " ignored for refs)\n" \
230 " prev-state:n/a (not valid for event references)\n" \
231 "=> err-state:%s core:%02u:\t" \
232 " EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
233 " event:0x%016" PRIx64 ": ptr:0x%" PRIx64 ""
236 #define EVSTATE_UNMARK_ERROR_FMT \
237 "ESV: Event:%" PRI_EVENT " state error - Invalid 'unmark'-API use\n"\
238 " prev-state:%s core:%02u:\t" \
239 " EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
240 "=> err-state:%s core:%02u:\t" \
241 " EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n"
244 #define EVSTATE__NO_PREV_STATE__ERROR_FMT \
245 "ESV: Event:%" PRI_EVENT " state error -- counts:\t" \
246 "send:%" PRIi16 " ref:%" PRIi16 " evgen:%" PRIu16 "(%" PRIu16 ")\n" \
248 " prev-state:n/a (disabled in conf)\n" \
249 "=> err-state:%s core:%02u:\t" \
250 " EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n" \
251 " event:0x%016" PRIx64 ": ptr:0x%" PRIx64 ""
254 #define EVSTATE__NO_PREV_STATE__UNMARK_ERROR_FMT \
255 "ESV: Event:%" PRI_EVENT " state error - Invalid 'unmark'-API use\n"\
256 " prev-state:n/a (disabled in conf)\n" \
257 "=> err-state:%s core:%02u:\t" \
258 " EO:%" PRI_EO "-\"%s\" Q:%" PRI_QUEUE "-\"%s\" u32[0]:%s\n"
264 esv_error(
const evstate_cnt_t cnt,
266 const uint16_t api_op,
bool is_unmark_error,
267 const char *
const help_str)
272 const em_event_t
event = event_hdr_to_event(ev_hdr);
273 const void *ev_ptr = NULL;
275 if (unlikely(prev_op > EVSTATE__LAST))
276 prev_op = EVSTATE__UNDEF;
285 char curr_payload[
sizeof(
"0x12345678 ")] =
"(n/a)";
286 char prev_payload[
sizeof(
"0x12345678 ")] =
"(n/a)";
293 ev_ptr = event_pointer(event);
295 esv_update_state(&err_state, api_op, ev_ptr);
303 snprintf(curr_payload,
sizeof(curr_payload),
305 curr_payload[
sizeof(curr_payload) - 1] =
'\0';
308 em_eo_t curr_eo = eo_idx2hdl(err_state.
eo_idx);
309 em_queue_t curr_queue = queue_idx2hdl(err_state.
queue_idx);
312 eo_elem = eo_elem_get(curr_eo);
314 eo_get_name(eo_elem, curr_eoname,
sizeof(curr_eoname));
316 q_elem = queue_elem_get(curr_queue);
318 queue_get_name(q_elem, curr_qname,
sizeof(curr_qname));
322 const uint16_t evgen_hdl = evhdl.evgen -
EVGEN_INIT;
326 if (
em_shm->opt.esv.store_state) {
332 if (
em_shm->opt.esv.store_first_u32) {
333 snprintf(prev_payload,
sizeof(prev_payload),
335 prev_payload[
sizeof(prev_payload) - 1] =
'\0';
338 em_eo_t prev_eo = eo_idx2hdl(prev_state.
eo_idx);
339 em_queue_t prev_queue = queue_idx2hdl(prev_state.
queue_idx);
342 eo_elem = eo_elem_get(prev_eo);
344 eo_get_name(eo_elem, prev_eoname,
sizeof(prev_eoname));
346 q_elem = queue_elem_get(prev_queue);
348 queue_get_name(q_elem, prev_qname,
sizeof(prev_qname));
353 err_info->escope, EVSTATE_REF_ERROR_FMT,
354 event, send_cnt, ref_cnt, evgen_cnt, help_str,
355 err_info->str, err_state.
core,
356 curr_eo, curr_eoname, curr_queue, curr_qname,
357 curr_payload, evhdl.event, evhdl.evptr);
358 }
else if (!is_unmark_error) {
361 err_info->escope, EVSTATE_ERROR_FMT,
362 event, send_cnt, ref_cnt, evgen_hdl, evgen_cnt, help_str,
363 prev_info->str, prev_state.
core, prev_eo, prev_eoname,
364 prev_queue, prev_qname, prev_payload,
365 err_info->str, err_state.
core, curr_eo, curr_eoname,
366 curr_queue, curr_qname, curr_payload,
367 evhdl.event, evhdl.evptr);
374 err_info->escope, EVSTATE_UNMARK_ERROR_FMT,
376 prev_info->str, prev_state.
core,
377 prev_eo, prev_eoname,
378 prev_queue, prev_qname, prev_payload,
379 err_info->str, err_state.
core,
380 curr_eo, curr_eoname,
381 curr_queue, curr_qname, curr_payload);
385 if (!is_unmark_error) {
388 err_info->escope, EVSTATE__NO_PREV_STATE__ERROR_FMT,
389 event, send_cnt, ref_cnt, evgen_hdl, evgen_cnt, help_str,
390 err_info->str, err_state.
core, curr_eo, curr_eoname,
391 curr_queue, curr_qname, curr_payload,
392 evhdl.event, evhdl.evptr);
399 err_info->escope, EVSTATE__NO_PREV_STATE__UNMARK_ERROR_FMT,
401 err_info->str, err_state.
core, curr_eo, curr_eoname,
402 curr_queue, curr_qname, curr_payload);
408 evstate_error(
const evstate_cnt_t cnt,
evhdl_t evhdl,
409 const event_hdr_t *
const ev_hdr,
const uint16_t api_op,
410 const char *
const help_str)
413 esv_error(cnt, evhdl, ev_hdr, api_op,
false, help_str);
420 evstate_unmark_error(
const event_hdr_t *
const ev_hdr,
const uint16_t api_op)
422 evstate_cnt_t dont_care = {.u64 = 0};
426 esv_error(dont_care, dont_care_hdl, ev_hdr, api_op,
true,
"n/a");
429 static inline em_event_t
430 esv_evinit(
const em_event_t event,
event_hdr_t *
const ev_hdr,
431 const evstate_cnt_t init_cnt,
const uint16_t api_op)
433 evhdl_t evhdl = {.event =
event};
436 ev_hdr->
event = evhdl.event;
439 __atomic_store_n(&ev_hdr->
state_cnt.u64, init_cnt.u64,
442 evhdr_update_state(ev_hdr, api_op);
448 esv_evinit_multi(em_event_t ev_tbl[],
450 const evstate_cnt_t init_cnt,
const uint16_t api_op)
454 for (
int i = 0; i < num; i++) {
456 ev_hdr_tbl[i]->
event = evhdl_tbl[i].event;
459 __atomic_store_n(&ev_hdr_tbl[i]->state_cnt.u64,
460 init_cnt.u64, __ATOMIC_RELAXED);
462 evhdr_update_state(ev_hdr_tbl[i], api_op);
466 static inline em_event_t
467 esv_evinit_ext(
const em_event_t event,
event_hdr_t *
const ev_hdr,
468 const uint16_t api_op)
475 evhdl_t evhdl = {.event =
event};
476 const evstate_cnt_t init = init_cnt_extev;
477 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
478 .ref_cnt = 0, .send_cnt = 1};
479 const evstate_cnt_t cnt = {.u64 = init.u64 - sub.u64};
481 evhdl.evgen = cnt.evgen;
482 ev_hdr->
event = evhdl.event;
485 __atomic_store_n(&ev_hdr->
state_cnt.u64, cnt.u64,
489 evhdr_update_state(ev_hdr, api_op);
494 static inline em_event_t
495 esv_em2usr(
const em_event_t event,
event_hdr_t *
const ev_hdr,
496 const evstate_cnt_t cnt,
const uint16_t api_op,
const bool is_revert)
499 evhdl_t evhdl = {.event =
event};
500 evstate_cnt_t new_cnt;
503 if (unlikely(is_revert)) {
505 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
506 cnt.u64, __ATOMIC_RELAXED);
509 new_cnt.u64 = __atomic_sub_fetch(&ev_hdr->
state_cnt.u64,
510 cnt.u64, __ATOMIC_RELAXED);
514 evhdl.evgen = new_cnt.evgen;
515 ev_hdr->
event = evhdl.event;
525 if (unlikely(send_cnt >= ref_cnt || send_cnt < 0)) {
527 evstate_error(new_cnt, evhdl, ev_hdr, api_op, help_str_em2usr);
535 evhdr_update_state(ev_hdr, api_op);
541 esv_em2usr_multi(em_event_t ev_tbl[],
543 const evstate_cnt_t cnt,
const uint16_t api_op,
544 const bool is_revert)
547 evstate_cnt_t new_cnt;
549 for (
int i = 0; i < num; i++) {
553 if (unlikely(is_revert)) {
556 __atomic_add_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
557 cnt.u64, __ATOMIC_RELAXED);
561 __atomic_sub_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
562 cnt.u64, __ATOMIC_RELAXED);
566 evhdl_tbl[i].evgen = new_cnt.evgen;
567 ev_hdr_tbl[i]->
event = evhdl_tbl[i].event;
577 if (unlikely(send_cnt >= ref_cnt || send_cnt < 0)) {
579 evstate_error(new_cnt, evhdl_tbl[i], ev_hdr_tbl[i],
580 api_op, help_str_em2usr);
588 evhdr_update_state(ev_hdr_tbl[i], api_op);
593 esv_usr2em(
const em_event_t event,
event_hdr_t *
const ev_hdr,
594 const evstate_cnt_t cnt,
const uint16_t api_op,
const bool is_revert)
597 evhdl_t evhdl = {.event =
event};
598 evstate_cnt_t new_cnt;
601 if (unlikely(is_revert)) {
603 new_cnt.u64 = __atomic_sub_fetch(&ev_hdr->
state_cnt.u64,
604 cnt.u64, __ATOMIC_RELAXED);
606 if (unlikely(new_cnt.evgen ==
EVGEN_INIT - 1)) {
609 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
610 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
611 add.u64, __ATOMIC_RELAXED);
615 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
616 cnt.u64, __ATOMIC_RELAXED);
618 if (unlikely(new_cnt.evgen ==
EVGEN_MAX)) {
621 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
622 __atomic_fetch_sub(&ev_hdr->
state_cnt.u64, sub.u64,
643 if (unlikely((send_cnt > ref_cnt || send_cnt < 0) ||
644 (!refs_used && evhdl.evgen != new_cnt.evgen))) {
645 const char *
const help_str = refs_used ? help_str_usr2em_ref : help_str_usr2em;
648 evstate_error(new_cnt, evhdl, ev_hdr, api_op, help_str);
656 evhdr_update_state(ev_hdr, api_op);
660 esv_usr2em_multi(
const em_event_t ev_tbl[],
662 const evstate_cnt_t cnt,
const uint16_t api_op,
663 const bool is_revert)
666 evstate_cnt_t new_cnt;
668 for (
int i = 0; i < num; i++) {
672 if (unlikely(is_revert)) {
675 __atomic_sub_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
676 cnt.u64, __ATOMIC_RELAXED);
678 if (unlikely(new_cnt.evgen ==
EVGEN_INIT - 1)) {
681 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
683 __atomic_add_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
684 add.u64, __ATOMIC_RELAXED);
689 __atomic_add_fetch(&ev_hdr_tbl[i]->state_cnt.u64,
690 cnt.u64, __ATOMIC_RELAXED);
692 if (unlikely(new_cnt.evgen ==
EVGEN_MAX)) {
695 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
696 __atomic_fetch_sub(&ev_hdr_tbl[i]->state_cnt.u64, sub.u64,
717 if (unlikely((send_cnt > ref_cnt || send_cnt < 0) ||
718 (!refs_used && evhdl_tbl[i].evgen != new_cnt.evgen))) {
720 evstate_error(new_cnt, evhdl_tbl[i], ev_hdr_tbl[i],
721 api_op, help_str_usr2em);
729 evhdr_update_state(ev_hdr_tbl[i], api_op);
735 return esv_evinit(event, ev_hdr, init_cnt_alloc, EVSTATE__PREALLOC);
739 const uint16_t api_op)
742 return esv_evinit(event, ev_hdr, init_cnt_alloc, api_op);
744 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
745 .ref_cnt = 1, .send_cnt = 0};
747 return esv_em2usr(event, ev_hdr, sub, api_op,
false);
752 return esv_evinit(event, ev_hdr, init_cnt_alloc, EVSTATE__TMO_CREATE);
758 if (!
em_shm->opt.esv.prealloc_pools) {
759 esv_evinit_multi(ev_tbl, ev_hdr_tbl, num,
760 init_cnt_alloc, EVSTATE__ALLOC_MULTI);
765 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
766 .ref_cnt = 1, .send_cnt = 0};
768 for (
int i = 0; i < num; i++) {
770 ev_tbl[i] = esv_evinit(ev_tbl[i], ev_hdr_tbl[i],
772 EVSTATE__ALLOC_MULTI);
774 ev_tbl[i] = esv_em2usr(ev_tbl[i], ev_hdr_tbl[i], sub,
775 EVSTATE__ALLOC_MULTI,
false);
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, EVSTATE__EVENT_REF,
false);
792 return esv_evinit_ext(event, ev_hdr, EVSTATE__INIT_EXTEV);
794 return esv_evinit(event, ev_hdr, init_cnt_alloc, EVSTATE__INIT);
802 evstate_cnt_t init_cnt;
805 api_op = EVSTATE__INIT_EXTEV_MULTI;
806 init_cnt = init_cnt_extev;
808 api_op = EVSTATE__INIT_MULTI;
809 init_cnt = init_cnt_alloc;
812 esv_evinit_multi(ev_tbl, ev_hdr_tbl, num,
842 static inline em_event_t
843 esv_update_ext(
const em_event_t event,
event_hdr_t *
const ev_hdr,
844 const uint16_t api_op)
846 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
847 .ref_cnt = 1, .send_cnt = 0};
848 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
849 .ref_cnt = 0, .send_cnt = 0};
850 const evstate_cnt_t cmb = {.u64 = add.u64 - sub.u64};
853 evhdl_t evhdl = {.event =
event};
854 evstate_cnt_t new_cnt;
857 new_cnt.u64 = __atomic_add_fetch(&ev_hdr->
state_cnt.u64,
858 cmb.u64, __ATOMIC_RELAXED);
860 if (unlikely(new_cnt.evgen ==
EVGEN_MAX)) {
863 .rsvd = 0, .ref_cnt = 0, .send_cnt = 0};
864 new_cnt.u64 = __atomic_sub_fetch(&ev_hdr->
state_cnt.u64, wrap.u64,
869 evhdl.evgen = new_cnt.evgen;
870 ev_hdr->
event = evhdl.event;
880 if (unlikely(send_cnt >= ref_cnt || send_cnt < 0)) {
882 evstate_error(new_cnt, evhdl, ev_hdr, api_op, help_str_em2usr);
890 evhdr_update_state(ev_hdr, api_op);
898 em_event_t ret_event;
902 ret_event = esv_update_ext(event, ev_hdr, EVSTATE__UPDATE_EXTEV);
905 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
906 .ref_cnt = 1, .send_cnt = 0};
908 ret_event = esv_em2usr(event, ev_hdr, sub, EVSTATE__UPDATE_EXTEV,
false);
915 const uint16_t api_op)
917 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
918 .ref_cnt = 1, .send_cnt = 0};
920 esv_usr2em(event, ev_hdr, add, api_op,
false);
924 const uint16_t api_op)
926 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
927 .ref_cnt = 1, .send_cnt = 0};
929 esv_usr2em(event, ev_hdr, sub, api_op,
true );
934 const uint16_t api_op)
936 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
937 .ref_cnt = 1, .send_cnt = 0};
939 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, add, api_op,
false);
944 const uint16_t api_op)
946 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
947 .ref_cnt = 1, .send_cnt = 0};
949 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, sub, api_op,
true );
953 const uint16_t api_op)
955 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
956 .ref_cnt = 0, .send_cnt = 1};
958 return esv_em2usr(event, ev_hdr, sub, api_op,
false);
962 const uint16_t api_op)
964 const evstate_cnt_t add = {.evgen = 0, .rsvd = 0,
965 .ref_cnt = 0, .send_cnt = 1};
967 return esv_em2usr(event, ev_hdr, add, api_op,
true );
972 const uint16_t api_op)
974 const evstate_cnt_t sub = {.evgen = 0, .rsvd = 0,
975 .ref_cnt = 0, .send_cnt = 1};
977 esv_em2usr_multi(ev_tbl, ev_hdr_tbl, num, sub, api_op,
false);
982 const uint16_t api_op)
984 const evstate_cnt_t add = {.evgen = 0, .rsvd = 0,
985 .ref_cnt = 0, .send_cnt = 1};
987 esv_em2usr_multi(ev_tbl, ev_hdr_tbl, num, add, api_op,
true );
991 const uint16_t api_op)
993 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
994 .ref_cnt = 0, .send_cnt = 1};
996 esv_usr2em(event, ev_hdr, add, api_op,
false);
1000 const uint16_t api_op)
1002 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
1003 .ref_cnt = 0, .send_cnt = 1};
1005 esv_usr2em(event, ev_hdr, sub, api_op,
true );
1010 const uint16_t api_op)
1012 const evstate_cnt_t add = {.evgen = 1, .rsvd = 0,
1013 .ref_cnt = 0, .send_cnt = 1};
1015 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, add, api_op,
false);
1020 const uint16_t api_op)
1022 const evstate_cnt_t sub = {.evgen = 1, .rsvd = 0,
1023 .ref_cnt = 0, .send_cnt = 1};
1025 esv_usr2em_multi(ev_tbl, ev_hdr_tbl, num, sub, api_op,
true );
1033 check_valid_unmark(
const event_hdr_t *ev_hdr, uint16_t api_op,
1034 const uint16_t expected_ops[],
const int num_ops)
1042 for (
int i = 0; i < num_ops; i++) {
1043 if (prev_op == expected_ops[i])
1048 evstate_unmark_error(ev_hdr, api_op);
1052 check_valid_unmark_multi(
event_hdr_t *
const ev_hdr_tbl[],
const int num_evs,
1053 uint16_t api_op,
const uint16_t expected_ops[],
const int num_ops)
1058 for (
int i = 0; i < num_evs; i++) {
1060 if (ev_hdr_tbl[i]->flags.refs_used)
1066 for (
int j = 0; j < num_ops; j++) {
1067 if (prev_op == expected_ops[j]) {
1074 if (unlikely(!is_valid))
1075 evstate_unmark_error(ev_hdr_tbl[i], api_op);
1081 if (
em_shm->opt.esv.store_state) {
1082 uint16_t expected_prev_ops[1] = {EVSTATE__MARK_SEND};
1087 check_valid_unmark(ev_hdr, EVSTATE__UNMARK_SEND,
1088 expected_prev_ops, 1);
1095 const uint16_t api_op)
1097 if (
em_shm->opt.esv.store_state) {
1098 uint16_t expected_prev_ops[2] = {EVSTATE__MARK_FREE,
1099 EVSTATE__MARK_FREE_MULTI};
1104 check_valid_unmark(ev_hdr, api_op, expected_prev_ops, 2);
1112 const uint16_t api_op)
1114 if (
em_shm->opt.esv.store_state) {
1115 uint16_t expected_prev_ops[2] = {EVSTATE__MARK_FREE_MULTI,
1116 EVSTATE__MARK_FREE};
1122 check_valid_unmark_multi(ev_hdr_tbl, num, api_op,
1123 expected_prev_ops, 2);
1129 static int read_config_file(
void)
1131 const char *conf_str;
1132 bool val_bool =
false;
1135 EM_PRINT(
"EM ESV config: (EM_ESV_ENABLE=%d)\n",
EM_ESV_ENABLE);
1140 conf_str =
"esv.enable";
1141 ret = em_libconfig_lookup_bool(&
em_shm->
libconfig, conf_str, &val_bool);
1142 if (unlikely(!ret)) {
1143 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1147 em_shm->opt.esv.enable = (int)val_bool;
1148 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
1151 if (!
em_shm->opt.esv.enable) {
1160 conf_str =
"esv.store_state";
1161 ret = em_libconfig_lookup_bool(&
em_shm->
libconfig, conf_str, &val_bool);
1162 if (unlikely(!ret)) {
1163 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1167 em_shm->opt.esv.store_state = (int)val_bool;
1168 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
1174 conf_str =
"esv.store_payload_first_u32";
1175 ret = em_libconfig_lookup_bool(&
em_shm->
libconfig, conf_str, &val_bool);
1176 if (unlikely(!ret)) {
1177 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1181 em_shm->opt.esv.store_first_u32 = (int)val_bool;
1182 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
1188 conf_str =
"esv.prealloc_pools";
1189 ret = em_libconfig_lookup_bool(&
em_shm->
libconfig, conf_str, &val_bool);
1190 if (unlikely(!ret)) {
1191 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
1195 em_shm->opt.esv.prealloc_pools = (int)val_bool;
1196 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false",
1204 if (read_config_file())
1212 const char *conf_str =
"esv.enable";
1213 bool val_bool =
false;
1216 EM_PRINT(
"EM ESV config: (EM_ESV_ENABLE=%d)\n",
EM_ESV_ENABLE);
1217 EM_PRINT(
" ESV disabled\n");
1219 ret = em_libconfig_lookup_bool(&
em_shm->
libconfig, conf_str, &val_bool);
1223 EM_PRINT(
" %s: %s(%d)\n", conf_str, val_bool ?
"true" :
"false", val_bool);
1225 if (unlikely(val_bool))
1226 EM_PRINT(
" WARNING: ESV disabled (build-time) - config file option IGNORED!\n");