78 em_queue_t shared_unsched_queue;
81 const char *err_str =
"";
83 DBG_PRINT(
"%s()\n", __func__);
91 shared_unsched_queue = queue_id2hdl(
em_shm->queue_tbl.shared_internal_queue_id);
94 param.
queue = shared_unsched_queue;
97 queue = queue_create_param(
"EMctrl-unschedQ-shared", ¶m, &err_str);
106 const int thr = odp_thread_id();
109 em_queue_t queue_req;
111 const char *err_str =
"";
113 snprintf(q_name,
sizeof(q_name),
"EMctrl-unschedQ-thr%d", thr);
116 DBG_PRINT(
"%s(): %s\n", __func__, q_name);
120 DBG_PRINT(
"%s(): thr:%d, %s already created - reusing\n",
121 __func__, thr, q_name);
125 if (unlikely(!q_elem || !queue_allocated(q_elem))) {
126 DBG_PRINT(
"%s(): q_elem invalid for %s\n",
140 queue_req = queue_id2hdl(
em_shm->queue_tbl.first_internal_queue_id + (uint16_t)thr);
143 param.
queue = queue_req;
147 queue = queue_create_param(q_name, ¶m, &err_str);
157 em_queue_t unsched_queue;
158 em_event_t unsched_event;
162 unsched_queue = queue_id2hdl(
em_shm->queue_tbl.shared_internal_queue_id);
170 if (unlikely(stat !=
EM_OK))
172 "shared unschedQ delete");
174 for (
int i = 0; i < MAX_INTERNAL_QUEUES - 1; i++) {
175 unsched_queue = queue_id2hdl(
em_shm->queue_tbl.first_internal_queue_id + i);
176 q_elem = queue_elem_get(unsched_queue);
178 if (!q_elem || !queue_allocated(q_elem) ||
190 if (unlikely(stat !=
EM_OK))
192 "core unschedQ:%d delete", i);
199 void (*f_done_callback)(
void *arg_ptr),
200 void *f_done_arg_ptr,
207 const int mask_count = odp_thrmask_count(thr_mask);
210 int unsent_count = mask_count;
212 em_event_t events[mask_count];
217 "Too large notif table (%i)", num_notif);
225 f_done_callback, f_done_arg_ptr,
226 num_notif, notif_tbl,
230 "Internal 'done' notif setup failed");
239 for (i = 0; i < mask_count - 1; i++) {
245 EM_ESCOPE_INTERNAL_NOTIF,
246 "Internal event alloc failed");
247 goto err_free_resources;
253 *i_event_tmp = *i_event;
256 events[i] = ctrl_event;
262 first_qidx = queue_id2idx(
em_shm->queue_tbl.first_internal_queue_id);
264 int thr = odp_thrmask_first(thr_mask);
272 queue_idx2hdl(first_qidx + thr),
274 if (unlikely(err !=
EM_OK)) {
276 "Event group send failed");
277 goto err_free_resources;
282 thr = odp_thrmask_next(thr_mask, thr);
289 for (i = sent_count; i < alloc_count; i++)
306 if (unlikely(ret !=
EM_OK))
308 "Event group %" PRI_EGRP " delete failed (ret=%u)",
309 i_ev->
done.event_group, ret);
312 if (i_ev->
done.f_done_callback != NULL)
313 i_ev->
done.f_done_callback(i_ev->
done.f_done_arg_ptr);
318 num_notif = i_ev->
done.num_notif;
322 if (unlikely(ret !=
EM_OK))
324 "em_send() of notifs(%d) failed",
333internal_event_receive(
void *eo_ctx, em_event_t event,
em_event_type_t type,
334 em_queue_t queue,
void *q_ctx)
343 if (unlikely(!i_event)) {
347 "Q:%" PRI_QUEUE ": Invalid event, evptr NULL", queue);
351 switch (i_event->
id) {
355 case EM_INTERNAL_DONE:
356 i_event__internal_done(i_event);
362 case QUEUE_GROUP_ADD_REQ:
363 i_event__qgrp_add_core_req(i_event);
369 case QUEUE_GROUP_REM_REQ:
370 i_event__qgrp_rem_core_req(i_event);
375 case EO_START_LOCAL_REQ:
376 case EO_START_SYNC_LOCAL_REQ:
377 case EO_STOP_LOCAL_REQ:
378 case EO_STOP_SYNC_LOCAL_REQ:
379 case EO_REM_QUEUE_LOCAL_REQ:
380 case EO_REM_QUEUE_SYNC_LOCAL_REQ:
381 case EO_REM_QUEUE_ALL_LOCAL_REQ:
382 case EO_REM_QUEUE_ALL_SYNC_LOCAL_REQ:
383 i_event__eo_local_func_call_req(i_event);
386 case TERM_THREAD_REQ:
387 i_event__term_thread_req(i_event);
392 EM_ESCOPE_INTERNAL_EVENT_RECV_FUNC,
393 "Internal ev-id:0x%" PRIx64
" Q:%" PRI_QUEUE "",
404 void (*f_done_callback)(
void *arg_ptr),
405 void *f_done_arg_ptr,
409 em_event_group_t event_group;
419 EM_ESCOPE_INTERNAL_DONE_W_NOTIF_REQ,
420 "Internal event 'DONE' alloc failed!");
428 EM_ESCOPE_INTERNAL_DONE_W_NOTIF_REQ,
429 "Event group create failed!");
434 i_event->
id = EM_INTERNAL_DONE;
435 i_event->
done.event_group = event_group;
436 i_event->
done.f_done_callback = f_done_callback;
437 i_event->
done.f_done_arg_ptr = f_done_arg_ptr;
438 i_event->
done.num_notif = num_notif;
440 for (
int i = 0; i < num_notif; i++)
441 i_event->
done.notif_tbl[i] = notif_tbl[i];
443 i_notif.
event = event;
445 i_notif.
queue = queue_id2hdl(
em_shm->queue_tbl.first_internal_queue_id +
446 (uint16_t)odp_thread_id());
448 i_notif.
queue = queue_id2hdl(
em_shm->queue_tbl.shared_internal_queue_id);
459 if (unlikely(err !=
EM_OK)) {
461 "Event group apply failed");
480 if (err ==
EM_OK && num > 0) {
481 for (
int i = 0; i < num; i++)
482 em_free(free_notif_tbl[i].event);
493 for (
int i = 0; i < num_notif; i++) {
494 const em_event_t
event = notif_tbl[i].
event;
495 const em_queue_t queue = notif_tbl[i].
queue;
496 const em_event_group_t egrp = notif_tbl[i].
egroup;
499 if (invalid_egrp(egrp))
504 if (unlikely(err !=
EM_OK)) {
520 const bool is_external = queue_external(notif->
queue);
525 if (unlikely(q_elem == NULL || !queue_allocated(q_elem)))
531 event_group_elem_get(notif->
egroup);
533 if (unlikely(egrp_elem == NULL ||
534 !event_group_allocated(egrp_elem)))
549 if (unlikely(num_notif > 0 && notif_tbl == NULL))
552 for (
int i = 0; i < num_notif; i++) {
554 if (unlikely(err !=
EM_OK))
565handle_ctrl_events(em_queue_t unsched_queue,
566 const em_event_t ev_tbl[],
const int num)
571 event_to_hdr_multi(ev_tbl, evhdr_tbl, num);
573 for (
int i = 0; i < num; i++) {
579 em_event_t
event = ev_tbl[i];
584 event_group_set_local(ev_hdr->
egrp, ev_hdr->
egrp_gen, 1);
586 internal_event_receive(NULL, event, event_type,
587 unsched_queue, NULL);
595 if (current_egrp_elem) {
600 event_group_count_decrement(1, current_egrp_elem);
619 const int deq_max = 16;
620 em_event_t thr_ev_tbl[deq_max];
621 em_event_t shared_ev_tbl[deq_max];
627 thr_num = queue_dequeue_multi(thr_unsch_qelem,
628 thr_ev_tbl, deq_max);
629 shared_num = queue_dequeue_multi(shared_unsch_qelem,
630 shared_ev_tbl, deq_max);
631 if (thr_num <= 0 && shared_num <= 0)
644 handle_ctrl_events(thr_unsched_queue, thr_ev_tbl, thr_num);
646 if (shared_num > 0) {
649 handle_ctrl_events(shared_unsched_queue, shared_ev_tbl, shared_num);
#define INTERNAL_ERROR(error, escope, fmt,...)
em_status_t send_ctrl_queue(em_event_t event, em_queue_t queue, em_event_group_t event_group)
em_status_t check_notif(const em_notif_t *const notif)
Check that the usage of a notification is valid.
em_status_t create_ctrl_queue(void)
Create EM's internal unscheduled control queues at startup - one per core.
int send_core_ctrl_events(const odp_thrmask_t *const thr_mask, em_event_t ctrl_event, void(*f_done_callback)(void *arg_ptr), void *f_done_arg_ptr, int num_notif, const em_notif_t notif_tbl[], bool sync_operation)
Sends an internal control event to each thread set in 'mask'.
em_event_group_t internal_done_w_notif_req(int event_group_count, void(*f_done_callback)(void *arg_ptr), void *f_done_arg_ptr, int num_notif, const em_notif_t notif_tbl[], bool sync_operation)
Helper func: Allocate & set up the internal 'done' event with function callbacks and notification eve...
void poll_unsched_ctrl_queue(void)
Poll EM's internal unscheduled control queues during dispatch.
em_status_t delete_ctrl_queues(void)
Delete EM's internal unscheduled control queues at teardown.
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.
em_status_t create_shared_ctrl_queue(void)
Create EM's internal shared unscheduled control queue at startup.
void evgrp_abort_delete(em_event_group_t event_group)
internal_done_w_notif_req() 'companion' to abort and delete the event group created by the mentioned ...
em_status_t send_notifs(const int num_notif, const em_notif_t notif_tbl[])
Helper func to send notifications events.
ENV_LOCAL em_locm_t em_locm
#define EM_EVENT_GROUP_MAX_NOTIF
#define EM_QUEUE_NAME_LEN
#define EM_EVENT_GROUP_UNDEF
em_status_t em_event_group_delete(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_status_t em_send_group(em_event_t event, em_queue_t queue, em_event_group_t event_group)
int em_event_group_notif(em_event_group_t event_group, int max_notif, em_notif_t notif_tbl[])
em_event_t em_alloc(uint32_t size, em_event_type_t type, em_pool_t pool)
em_status_t em_send(em_event_t event, em_queue_t queue)
void em_free(em_event_t event)
void * em_event_pointer(em_event_t event)
em_event_t em_queue_dequeue(em_queue_t queue)
em_status_t em_queue_delete(em_queue_t queue)
void em_queue_param_init(em_queue_param_t *param)
#define EM_QUEUE_FLAG_DEQ_NOT_MTSAFE
em_queue_t em_queue_find(const char *name)
@ EM_QUEUE_TYPE_UNSCHEDULED
@ EM_SCHED_CONTEXT_TYPE_NONE
em_sched_context_type_t sched_context_type
event_group_elem_t * egrp_elem
queue_elem_t * sched_q_elem
em_locm_current_t current
em_event_type_t event_type
em_queue_t shared_unsched_queue
em_queue_t thr_unsched_queue
queue_elem_t * thr_unsched_qelem
queue_elem_t * shared_unsched_qelem
struct internal_event_t::@49 done