64static ENV_LOCAL
unsigned int _egrp_tbl_iter_idx;
68 em_event_group_t egrp;
72 egrp = event_group_alloc();
74 unsigned int evgrp_cnt = 0;
78 "Event group alloc failed! evgrps created: %u, max evgrps: %u",
83 egrp_elem = event_group_elem_get(egrp);
105 RETURN_ERROR_IF(egrp_elem == NULL || !event_group_allocated(egrp_elem),
107 "Invalid event group: %" PRI_EGRP "", event_group);
111 if (unlikely(egrp_cnt.
applied))
113 "Event group:%" PRI_EGRP " not in a state for delete!",
118 status = event_group_free(event_group);
120 "Event Group delete failed!");
133 "Invalid args: event group:%" PRI_EGRP ", count:%d [1, %llu]",
138 "Event group:%" PRI_EGRP " not created!", event_group);
143 "Invalid notif cfg given!");
152 if (unlikely(egrp_cnt.
applied))
154 EM_ESCOPE_EVENT_GROUP_APPLY, egrp_cnt,
155 "Event group %" PRI_EGRP " in use, cannot apply!",
160 for (
int i = 0; i < num_notif; i++) {
188 const uint32_t incr = (uint32_t)count;
194 "No current event group (%" PRI_EGRP ")", egrp);
196 EM_ESCOPE_EVENT_GROUP_INCREMENT,
197 "Invalid arg: count:%d", count);
202 "Current event group in a bad state (%" PRI_EGRP ")", egrp);
214 EM_ESCOPE_EVENT_GROUP_INCREMENT, egrp_cnt,
215 "Expired event group (%" PRI_EGRP ") or not applied:\n"
216 " curr gen:%u", egrp);
222 EM_ESCOPE_EVENT_GROUP_INCREMENT, egrp_cnt,
223 "Event group %" PRI_EGRP " counter would overflow:\n"
224 " count + increment(%u) > max(%u)",
246 "Invalid event group: %" PRI_EGRP "",
251 if (unlikely(
EM_CHECK_LEVEL >= 2 && !event_group_allocated(egrp_elem))) {
253 "Event group: %" PRI_EGRP " not created",
280 if (unlikely(!current_egrp_elem))
301 "Invalid event group: %" PRI_EGRP "", event_group);
305 "Invalid event group: %" PRI_EGRP "", event_group);
308 "Cannot assign event group %" PRI_EGRP ",\n"
309 "not called from EO-receive or no events(%d)!",
310 event_group, num_events);
314 "Cannot assign event group %" PRI_EGRP ",\n"
315 "Event group %" PRI_EGRP " already assigned!",
324 if (unlikely(!egrp_cnt.
applied))
326 EM_ESCOPE_EVENT_GROUP_ASSIGN, egrp_cnt,
327 "Cannot assign event group %" PRI_EGRP ",\n"
328 "has not been applied!", event_group);
344 EM_ESCOPE_EVENT_GROUP_ASSIGN, egrp_cnt,
345 "Cannot assign event group %" PRI_EGRP ",\n"
346 "has not been applied or too many events:%d!",
347 event_group, num_events);
371 "Invalid event group: %" PRI_EGRP "", event_group);
376 "Event group: %" PRI_EGRP " not created", event_group);
382 if (unlikely(!egrp_cnt.
applied)) {
384 DBG_PRINT(
"%s():Event group:%" PRI_EGRP " abort late, notifs already sent\n"
385 " pre_cnt:%u post_cnt:%u, gen:%u, applied:%s\n",
386 __func__, event_group, (uint32_t)egrp_cnt.
pre_cnt,
387 (uint32_t)egrp_cnt.
post_cnt, (uint32_t)egrp_cnt.
gen,
388 egrp_cnt.
applied ?
"true" :
"false");
415 unlikely(egrp_elem == NULL || max_notif < 0)) {
417 "Invalid args: evgrp:%" PRI_EGRP ", notifs:%d",
418 event_group, max_notif);
422 if (unlikely(
EM_CHECK_LEVEL >= 2 && !event_group_allocated(egrp_elem))) {
424 "Event group:%" PRI_EGRP " not created", event_group);
428 if (unlikely(max_notif == 0))
431 if (unlikely(notif_tbl == NULL)) {
433 "Invalid notif_tbl[] given");
442 num_notif = max_notif < egrp_elem->
num_notif ?
445 for (
int i = 0; i < num_notif; i++) {
461send_external_egrp(em_event_t event,
event_hdr_t *
const ev_hdr,
462 em_queue_t queue, em_event_group_t event_group,
466 call_api_hooks_send(&event, 1, queue, event_group);
468 em_status_t stat = send_chaining_egrp(event, ev_hdr, queue, egrp_elem);
474 "send_chaining_egrp: Q:%" PRI_QUEUE "", queue);
484send_external_egrp_multi(
const em_event_t events[],
event_hdr_t *ev_hdrs[],
int num,
485 em_queue_t queue, em_event_group_t event_group,
489 call_api_hooks_send(events, num, queue, event_group);
491 int num_sent = send_chaining_egrp_multi(events, ev_hdrs, num,
495 "send_chaining_egrp_multi: req:%d, sent:%d",
514 ev_hdr->
egrp = egrp_elem->event_group;
526egrp_tag_events_multi(
event_hdr_t *
const ev_hdrs[],
int num,
527 em_event_group_t event_group,
530 for (
int i = 0; i < num; i++)
531 ev_hdrs[i]->egrp = event_group;
538 uint32_t egrp_gen = egrp_cnt.
gen;
540 for (
int i = 0; i < num; i++)
541 ev_hdrs[i]->egrp_gen = egrp_gen;
554send_egrp_common(em_event_t event,
event_hdr_t *ev_hdr,
560 evstate_usr2em(event, ev_hdr, EVSTATE__SEND_EGRP);
562 switch (q_elem->
type) {
566 stat = send_sched(event, q_elem);
575 stat = queue_unsched_enqueue(event, q_elem);
578 stat = send_aggr(event, ev_hdr, q_elem);
581 stat = send_local(event, q_elem);
589 if (unlikely(stat !=
EM_OK && esv_enabled()))
590 evstate_usr2em_revert(event, ev_hdr, EVSTATE__SEND_EGRP__FAIL);
604send_egrp_common_multi(
const em_event_t events[],
event_hdr_t *ev_hdrs[],
610 evstate_usr2em_multi(events, ev_hdrs, num, EVSTATE__SEND_EGRP_MULTI);
612 switch (q_elem->
type) {
616 num_sent = send_sched_multi(events, num, q_elem);
623 num_sent = queue_unsched_enqueue_multi(events, num, q_elem);
626 num_sent = send_aggr_multi(events, ev_hdrs, num, q_elem);
629 num_sent = send_local_multi(events, num, q_elem);
637 if (unlikely(num_sent != num && esv_enabled()))
638 evstate_usr2em_revert_multi(&events[num_sent],
641 EVSTATE__SEND_EGRP_MULTI__FAIL);
647 em_event_group_t event_group)
650 const bool is_external = queue_external(queue);
657 "Invalid event group:%" PRI_EGRP "", event_group);
659 !event_group_allocated(egrp_elem),
661 "Event group:%" PRI_EGRP " not created", event_group);
671 "Event has references: can't use references with event groups");
679 "Event of type %u can't be sent with %s()",
683 egrp_tag_event(ev_hdr, egrp_elem);
689 return send_external_egrp(event, ev_hdr, queue,
690 event_group, egrp_elem);
712 "Event group not supported with unscheduled queue:%" PRI_QUEUE "",
721 evstate_usr2em(event, ev_hdr, EVSTATE__SEND_EGRP);
723 if (likely(eo_start_buffer_events(&event, 1, queue) == 1))
728 evstate_usr2em_revert(event, ev_hdr, EVSTATE__SEND_EGRP__FAIL);
732 "EO-start event buffering failed, Q:%" PRI_QUEUE "",
737 call_api_hooks_send(&event, 1, queue, event_group);
742 em_status_t stat = send_egrp_common(event, ev_hdr, q_elem);
744 if (likely(stat ==
EM_OK))
750 queue, q_elem->
type);
757send_grpmulti_check(
const em_event_t events[],
int num,
758 em_event_group_t event_group,
762 unlikely(!events || num <= 0 ||
768 !event_group_allocated(egrp_elem)))
776 if (unlikely(i != num))
788send_egrp_multi_eo_start(
const em_event_t events[],
event_hdr_t *ev_hdrs[],
789 int num, em_queue_t queue)
792 evstate_usr2em_multi(events, ev_hdrs, num,
793 EVSTATE__SEND_EGRP_MULTI);
795 int num_sent = eo_start_buffer_events(events, num, queue);
797 if (likely(num_sent == num))
802 evstate_usr2em_revert_multi(&events[num_sent],
805 EVSTATE__SEND_EGRP_MULTI__FAIL);
808 "EO-start event buffering failed: req:%d, sent:%d",
814 em_event_group_t event_group)
817 const bool is_external = queue_external(queue);
820 em_status_t err = send_grpmulti_check(events, num, event_group, egrp_elem);
822 if (unlikely(err !=
EM_OK)) {
824 "Invalid args: events:%p num:%d event_group:%" PRI_EGRP "",
825 events, num, event_group);
835 for (
int i = 0; i < num; i++) {
836 if (likely(!event_has_ref(events[i])))
840 "event[%d] has references: can't use with event groups", i);
845 event_to_hdr_multi(events, ev_hdrs, num);
849 for (
int i = 0; i < num; i++) {
853 "Event[%d] of type %u can't be sent with %s()",
854 i, ev_hdrs[i]->event_type, __func__);
861 egrp_tag_events_multi(ev_hdrs, num, event_group, egrp_elem);
867 return send_external_egrp_multi(events, ev_hdrs, num, queue,
868 event_group, egrp_elem);
893 "Event group not supported with unscheduled queue:%" PRI_QUEUE "",
903 return send_egrp_multi_eo_start(events, ev_hdrs, num, queue);
906 call_api_hooks_send(events, num, queue, event_group);
911 int num_sent = send_egrp_common_multi(events, ev_hdrs, num, q_elem);
915 "send-egrp-multi failed: req:%d, sent:%d",
922 em_event_group_t event_group)
930 (!q_elem || !queue_allocated(q_elem)),
932 "Invalid ctrl queue:%" PRI_QUEUE "", queue);
935 egrp_tag_event(ev_hdr, egrp_elem);
937 em_status_t stat = send_egrp_common(event, ev_hdr, q_elem);
939 if (likely(stat ==
EM_OK))
945 queue, q_elem->
type);
951 em_shm->event_group_tbl.egrp_elem;
953 const unsigned int egrp_count = event_group_count();
955 _egrp_tbl_iter_idx = 0;
960 if (egrp_count == 0) {
966 while (!event_group_allocated(egrp_elem)) {
967 _egrp_tbl_iter_idx++;
970 egrp_elem = &egrp_elem_tbl[_egrp_tbl_iter_idx];
973 return egrp_idx2hdl(_egrp_tbl_iter_idx);
981 _egrp_tbl_iter_idx++;
984 em_shm->event_group_tbl.egrp_elem;
986 &egrp_elem_tbl[_egrp_tbl_iter_idx];
989 while (!event_group_allocated(egrp_elem)) {
990 _egrp_tbl_iter_idx++;
993 egrp_elem = &egrp_elem_tbl[_egrp_tbl_iter_idx];
996 return egrp_idx2hdl(_egrp_tbl_iter_idx);
1001 return (uint64_t)event_group;
#define INTERNAL_ERROR(error, escope, fmt,...)
#define RETURN_ERROR_IF(cond, error, escope, fmt,...)
em_status_t send_ctrl_queue(em_event_t event, em_queue_t queue, em_event_group_t event_group)
#define EGRP_CNT_ERROR(err, escope, egrp_cnt, fmt,...)
em_status_t check_notif_tbl(const int num_notif, const em_notif_t notif_tbl[])
Check that the usage of a table of notifications is valid.
ENV_LOCAL em_locm_t em_locm
#define EM_EVENT_GROUP_SAFE_MODE
#define EM_MAX_EVENT_GROUPS
#define EM_API_HOOKS_ENABLE
#define EM_EVENT_GROUP_UNDEF
@ EM_ERR_OPERATION_FAILED
uint64_t em_event_group_to_u64(em_event_group_t event_group)
em_event_group_t em_event_group_next(void)
void em_event_group_processing_end(void)
em_status_t em_event_group_delete(em_event_group_t event_group)
int em_event_group_is_ready(em_event_group_t event_group)
em_event_group_t em_event_group_create(void)
em_status_t em_event_group_abort(em_event_group_t event_group)
em_status_t em_event_group_apply(em_event_group_t event_group, int count, int num_notif, const em_notif_t notif_tbl[])
em_event_group_t em_event_group_first(unsigned int *num)
int em_send_group_multi(const em_event_t events[], int num, em_queue_t queue, em_event_group_t event_group)
em_event_group_t em_event_group_current(void)
em_status_t em_send_group(em_event_t event, em_queue_t queue, em_event_group_t event_group)
em_status_t em_event_group_increment(int count)
int em_event_group_notif(em_event_group_t event_group, int max_notif, em_notif_t notif_tbl[])
em_status_t em_event_group_assign(em_event_group_t event_group)
@ EM_EVENT_TYPE_TIMER_IND
@ EM_QUEUE_TYPE_UNSCHEDULED
event_group_elem_t * egrp_elem
em_locm_current_t current
eo_elem_t * start_eo_elem
em_notif_t notif_tbl[EM_EVENT_GROUP_MAX_NOTIF]
em_event_type_t event_type