33 #define EM_Q_BASENAME "EM_Q_"
46 queue_init_prio_map(
int minp,
int maxp,
int nump);
48 queue_init_prio_legacy(
int minp,
int maxp);
50 queue_init_prio_adaptive(
int minp,
int maxp,
int nump);
52 queue_init_prio_custom(
int minp,
int maxp);
55 queue_create_check_sched(
const queue_setup_t *setup,
const char **err_str);
59 const char **err_str);
62 odp_queue_param_t *odp_queue_param);
65 const char **err_str);
68 const char **err_str);
71 const char **err_str);
74 const char **err_str);
84 read_config_file(
void)
90 EM_PRINT(
"EM-queue config:\n");
95 conf_str =
"queue.max_num";
98 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found.\n", conf_str);
104 "Bad config value '%s = %d', Value must be larger than %d\n"
105 "to have space for static queues, internal ctrl queues and\n"
106 "at least one dynamic queue.\n",
111 if ((
unsigned int)val > UINT16_MAX) {
112 EM_LOG(EM_LOG_ERR,
"Bad config value '%s = %d', Value > UINT16_MAX\n",
117 if ((
unsigned int)val >
em_shm->queue_tbl.odp_queue_capability.max_queues) {
118 EM_LOG(EM_LOG_ERR,
"Bad config value '%s = %d', Value > odp-max-queues:%u\n",
119 conf_str, val,
em_shm->queue_tbl.odp_queue_capability.max_queues);
124 em_shm->opt.queue.max_num = (
unsigned int)val;
125 EM_PRINT(
" %s: %d\n", conf_str, val);
130 conf_str =
"queue.min_events_default";
132 if (unlikely(!ret)) {
133 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found.\n", conf_str);
137 EM_LOG(EM_LOG_ERR,
"Bad config value '%s = %d'\n",
142 em_shm->opt.queue.min_events_default = val;
143 EM_PRINT(
" %s: %d\n", conf_str, val);
148 conf_str =
"queue.priority.map_mode";
150 if (unlikely(!ret)) {
151 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found\n", conf_str);
154 if (val < 0 || val > 2) {
155 EM_LOG(EM_LOG_ERR,
"Bad config value '%s = %d'\n", conf_str, val);
158 em_shm->opt.queue.priority.map_mode = val;
159 EM_PRINT(
" %s: %d\n", conf_str, val);
162 conf_str =
"queue.priority.custom_map";
164 em_shm->opt.queue.priority.custom_map,
166 if (unlikely(!ret)) {
167 EM_LOG(EM_LOG_ERR,
"Config option '%s' not found or invalid\n", conf_str);
170 EM_PRINT(
" %s: [", conf_str);
172 EM_PRINT(
"%d",
em_shm->opt.queue.priority.custom_map[i]);
187 int min_qidx,
int max_qidx)
189 const uint32_t objpool_subpools = MIN(4, OBJSUBPOOLS_MAX);
190 const int qs_per_pool = (max_qidx - min_qidx + 1);
191 int qs_per_subpool = qs_per_pool / objpool_subpools;
192 int qs_leftover = qs_per_pool % objpool_subpools;
193 uint32_t subpool_idx = 0;
196 if (objpool_init(&queue_pool->objpool, objpool_subpools) != 0)
199 for (
int i = min_qidx; i <= max_qidx; i++) {
200 objpool_add(&queue_pool->objpool, subpool_idx,
201 &queue_tbl->queue_elem[i].queue_pool_elem);
203 if (add_cnt == qs_per_subpool + qs_leftover) {
221 odp_queue_capability_t *
const odp_queue_capa =
223 odp_schedule_capability_t *
const odp_sched_capa =
232 env_atomic32_init(&
em_shm->queue_count);
233 env_atomic32_init(&
em_shm->queue_tbl.output_queue_count);
236 ret = odp_queue_capability(odp_queue_capa);
238 "odp_queue_capability():%d failed", ret);
241 ret = odp_schedule_capability(odp_sched_capa);
243 "odp_schedule_capability():%d failed", ret);
245 if (read_config_file())
248 unsigned int max_queues =
em_shm->opt.queue.max_num;
250 size_t qelem_tbl_sz =
sizeof(
queue_elem_t) * max_queues;
252 size_t shm_sz = qelem_tbl_sz + qname_tbl_sz;
254 void *shm_tbl = env_shared_reserve(
"EM q_elem tbl and names", shm_sz);
257 "env_shared_reserve() failed when reserving \"EM q_elem tbl and names\"");
258 memset(shm_tbl, 0, shm_sz);
261 em_shm->queue_tbl.queue_elem = shm_tbl;
265 for (
unsigned int i = 0; i < max_queues; i++)
266 queue_tbl->queue_elem[i].queue = (uint32_t)(uintptr_t)queue_idx2hdl(i);
270 max = queue_id2idx(LAST_INTERNAL_QUEUE);
271 if (queue_pool_init(queue_tbl, queue_pool_static, min, max) != 0)
277 min = queue_id2idx(FIRST_DYN_QUEUE);
278 max = queue_id2idx(last_dyn_queue);
279 if (queue_pool_init(queue_tbl, queue_pool, min, max) != 0)
283 min = odp_schedule_min_prio();
284 max = odp_schedule_max_prio();
288 "mapping odp priorities failed: %d", ret);
292 em_shm->queue_tbl.output_queue_idx_free[i] =
true;
306 odp_stash_capability_t stash_capa;
307 odp_stash_param_t stash_param;
308 unsigned int num_obj = 0;
310 char name[ODP_STASH_NAME_LEN];
312 int ret = odp_stash_capability(&stash_capa, ODP_STASH_TYPE_FIFO);
317 odp_stash_param_init(&stash_param);
319 stash_param.type = ODP_STASH_TYPE_FIFO;
320 stash_param.put_mode = ODP_STASH_OP_ST;
321 stash_param.get_mode = ODP_STASH_OP_ST;
324 num_obj =
em_shm->opt.queue.min_events_default;
326 stash_param.num_obj = num_obj;
329 stash_param.obj_size =
sizeof(uint64_t);
330 if (stash_param.num_obj > stash_capa.max_num.u64) {
332 "%s(): req stash.num_obj(%" PRIu64
") > capa.max_num.u64(%" PRIu64
").\n"
333 " ==> using max value:%" PRIu64
"\n", __func__,
334 stash_param.num_obj, stash_capa.max_num.u64, stash_capa.max_num.u64);
335 stash_param.num_obj = stash_capa.max_num.u64;
338 stash_param.cache_size = 0;
343 snprintf(name,
sizeof(name),
344 "local-q:c%02d:prio%d", core, prio);
345 name[
sizeof(name) - 1] =
'\0';
349 odp_stash_create(name, &stash_param);
375 int num = next_local_queue_events(entry_tbl ,
380 for (
int i = 0; i < num; i++)
381 ev_tbl[i] = (em_event_t)(uintptr_t)entry_tbl[i].evptr;
383 event_to_hdr_multi(ev_tbl, ev_hdr_tbl, num);
387 EVSTATE__TERM_CORE__QUEUE_LOCAL);
394 if (unlikely(ret != 0))
420 queue_pool_elem = objpool_rem(&
em_shm->queue_pool.objpool,
422 if (unlikely(queue_pool_elem == NULL)) {
423 *err_str =
"queue pool element alloc failed!";
426 queue_elem = queue_poolelem2queue(queue_pool_elem);
434 if (iq.device_id !=
em_shm->conf.device_id ||
436 iq.queue_id > LAST_INTERNAL_QUEUE) {
437 *err_str =
"Invalid queue requested or handle not from static range!";
441 queue_elem = queue_elem_get(queue);
442 if (unlikely(queue_elem == NULL)) {
443 *err_str =
"queue_elem ptr NULL!";
447 if (queue_allocated(queue_elem)) {
448 *err_str =
"queue already allocated!";
452 int ret = objpool_rem_elem(&
em_shm->queue_pool_static.objpool,
454 if (unlikely(ret != 0)) {
455 *err_str =
"static queue pool element alloc failed!";
460 env_atomic32_inc(&
em_shm->queue_count);
461 return (em_queue_t)(uintptr_t)queue_elem->
queue;
472 if (unlikely(queue_elem == NULL))
476 iq.queue_id <= LAST_INTERNAL_QUEUE)
477 objpool = &
em_shm->queue_pool_static.objpool;
479 objpool = &
em_shm->queue_pool.objpool;
487 env_atomic32_dec(&
em_shm->queue_count);
492 queue_create_check_sched(
const queue_setup_t *setup,
const char **err_str)
497 queue_group_elem = queue_group_elem_get(setup->queue_group);
499 if (unlikely(queue_group_elem == NULL || !queue_group_allocated(queue_group_elem))) {
500 *err_str =
"Invalid queue group!";
505 ag_elem = atomic_group_elem_get(setup->atomic_group);
506 if (unlikely(ag_elem == NULL || !atomic_group_allocated(ag_elem))) {
507 *err_str =
"Invalid atomic group!";
513 *err_str =
"Invalid queue priority!";
520 queue_create_check_args(
const queue_setup_t *setup,
const char **err_str)
526 return queue_create_check_sched(setup, err_str);
529 switch (setup->type) {
533 *err_str =
"Invalid priority for unsched queue!";
537 *err_str =
"Queue group not used with unsched queues!";
541 *err_str =
"Atomic group not used with unsched queues!";
549 *err_str =
"Queue group not used with local queues!";
553 *err_str =
"Atomic group not used with local queues!";
557 *err_str =
"Invalid queue priority!";
565 *err_str =
"Queue group not used with output queues!";
569 *err_str =
"Atomic group not used with output queues!";
572 if (unlikely(setup->conf == NULL ||
574 setup->conf->
conf == NULL)) {
575 *err_str =
"Invalid output queue conf";
581 *err_str =
"Unknown queue type";
593 em_queue_group_t queue_group, em_queue_t queue_req,
595 const char **err_str)
601 conf = &default_queue_conf;
603 queue_setup_t setup = {.name = name, .type = type, .prio = prio,
604 .atomic_group = atomic_group,
605 .queue_group = queue_group, .conf = conf};
607 err = queue_create_check_args(&setup, err_str);
616 const char *alloc_err_str =
"";
618 em_queue_t queue =
queue_alloc(queue_req, &alloc_err_str);
621 *err_str = alloc_err_str;
624 if (unlikely(queue_req !=
EM_QUEUE_UNDEF && queue_req != queue)) {
626 *err_str =
"Failed to allocate the requested queue!";
632 if (unlikely(!queue_elem)) {
634 *err_str =
"Queue elem NULL!";
641 err = queue_setup(queue_elem, &setup, err_str);
657 em_queue_t queue = (em_queue_t)(uintptr_t)queue_elem->
queue;
660 if (unlikely(!queue_allocated(queue_elem)))
663 old_state = queue_elem->
state;
672 "EM-Q:%" PRI_QUEUE " inv. state change:%d=>%d",
673 queue, old_state, new_state);
683 !queue_group_allocated(queue_group_elem),
685 "Invalid queue group: %" PRI_QGRP "",
689 queue_group_rem_queue_list(queue_group_elem, queue_elem);
693 env_spinlock_t *
const lock = &queue_elem->output.
lock;
696 env_spinlock_lock(lock);
698 output_queue_drain(queue_elem);
699 env_spinlock_unlock(lock);
707 env_spinlock_lock(&
em_shm->queue_tbl.output_queue_lock);
708 em_shm->queue_tbl.output_queue_idx_free[q_out->
idx] =
true;
709 env_atomic32_dec(&
em_shm->queue_tbl.output_queue_count);
710 env_spinlock_unlock(&
em_shm->queue_tbl.output_queue_lock);
713 if (queue_elem->
odp_queue != ODP_QUEUE_INVALID &&
715 int err = odp_queue_destroy(queue_elem->
odp_queue);
718 "EM-Q:%" PRI_QUEUE ":odp_queue_destroy(" PRIu64
"):%d",
719 queue, odp_queue_to_u64(queue_elem->
odp_queue),
723 queue_elem->
odp_queue = ODP_QUEUE_INVALID;
726 em_shm->queue_tbl.name[queue_hdl2idx(queue)][0] =
'\0';
731 return queue_free(queue);
739 const char **err_str)
746 switch (setup->type) {
750 ret = queue_setup_scheduled(q_elem, setup, err_str);
753 ret = queue_setup_unscheduled(q_elem, setup, err_str);
756 ret = queue_setup_local(q_elem, setup, err_str);
759 ret = queue_setup_output(q_elem, setup, err_str);
762 *err_str =
"Queue setup: unknown queue type";
782 const em_queue_t queue = (em_queue_t)(uintptr_t)q_elem->
queue;
783 char *
const qname = &
em_shm->queue_tbl.name[queue_hdl2idx(queue)][0];
793 "%s%" PRI_QUEUE "", EM_Q_BASENAME, queue);
796 q_elem->flags.all = 0;
798 q_elem->
type = (uint8_t)setup->type;
799 q_elem->
priority = (uint8_t)setup->prio;
829 odp_queue_param_t *odp_queue_param )
839 odp_queue_param->nonblocking = ODP_NONBLOCKING_WF;
841 odp_queue_param->nonblocking = ODP_NONBLOCKING_LF;
844 odp_queue_param->enq_mode = ODP_QUEUE_OP_MT_UNSAFE;
846 odp_queue_param->deq_mode = ODP_QUEUE_OP_MT_UNSAFE;
854 unsigned int size =
em_shm->opt.queue.min_events_default;
857 odp_queue_param->size = size;
869 const odp_queue_param_t *odp_queue_param)
871 char odp_name[ODP_QUEUE_NAME_LEN];
872 odp_queue_t odp_queue;
874 (void)queue_get_name(q_elem, odp_name,
sizeof(odp_name));
876 odp_queue = odp_queue_create(odp_name, odp_queue_param);
877 if (unlikely(odp_queue == ODP_QUEUE_INVALID))
899 if (unlikely(qgrp_elem == NULL)) {
900 *err_str =
"Q-setup-sched: invalid queue group!";
904 q_elem->
priority = (uint8_t)setup->prio;
905 q_elem->
type = (uint8_t)setup->type;
922 odp_queue_param_t odp_queue_param;
924 odp_schedule_sync_t odp_schedule_sync = ODP_SCHED_SYNC_PARALLEL;
925 odp_schedule_prio_t odp_prio = odp_schedule_min_prio();
928 odp_queue_param_init(&odp_queue_param);
930 queue_setup_odp_common(setup, &odp_queue_param );
932 err = scheduled_queue_type_em2odp(setup->type,
933 &odp_schedule_sync );
935 *err_str =
"Q-setup-sched: invalid queue type!";
939 err = prio_em2odp(setup->prio, &odp_prio );
941 *err_str =
"Q-setup-sched: invalid queue priority!";
945 odp_queue_param.type = ODP_QUEUE_TYPE_SCHED;
946 odp_queue_param.sched.prio = odp_prio;
947 odp_queue_param.sched.sync = odp_schedule_sync;
951 const odp_schedule_capability_t *odp_sched_capa =
952 &
em_shm->queue_tbl.odp_schedule_capability;
958 if (odp_queue_param.nonblocking == ODP_NONBLOCKING_LF &&
959 odp_sched_capa->lockfree_queues == ODP_SUPPORT_NO) {
960 *err_str =
"Q-setup-sched: non-blocking, lock-free sched queues unavailable";
963 if (odp_queue_param.nonblocking == ODP_NONBLOCKING_WF &&
964 odp_sched_capa->waitfree_queues == ODP_SUPPORT_NO) {
965 *err_str =
"Q-setup-sched: non-blocking, wait-free sched queues unavailable";
968 if (odp_queue_param.enq_mode != ODP_QUEUE_OP_MT ||
969 odp_queue_param.deq_mode != ODP_QUEUE_OP_MT) {
970 *err_str =
"Q-setup-sched: invalid flag: scheduled queues must be MT-safe";
981 odp_queue_param.context = q_elem;
987 odp_queue_param.context_len =
sizeof(*q_elem);
989 err = create_odp_queue(q_elem, &odp_queue_param);
991 *err_str =
"Q-setup-sched: scheduled odp queue creation failed!";
998 queue_group_add_queue_list(qgrp_elem, q_elem);
1017 q_elem->
state = EM_QUEUE_STATE_UNSCHEDULED;
1022 odp_queue_param_t odp_queue_param;
1024 const odp_queue_capability_t *odp_queue_capa =
1025 &
em_shm->queue_tbl.odp_queue_capability;
1028 odp_queue_param_init(&odp_queue_param);
1030 queue_setup_odp_common(setup, &odp_queue_param);
1032 odp_queue_param.type = ODP_QUEUE_TYPE_PLAIN;
1034 odp_queue_param.order = ODP_QUEUE_ORDER_IGNORE;
1040 if (odp_queue_param.nonblocking == ODP_NONBLOCKING_LF &&
1041 odp_queue_capa->plain.lockfree.max_num == 0) {
1042 *err_str =
"Q-setup-unsched: non-blocking, lock-free unsched queues unavailable";
1045 if (odp_queue_param.nonblocking == ODP_NONBLOCKING_WF &&
1046 odp_queue_capa->plain.waitfree.max_num == 0) {
1047 *err_str =
"Q-setup-unsched: non-blocking, wait-free unsched queues unavailable";
1057 odp_queue_param.context = q_elem;
1063 odp_queue_param.context_len =
sizeof(*q_elem);
1065 int err = create_odp_queue(q_elem, &odp_queue_param);
1067 if (unlikely(err)) {
1068 *err_str =
"Q-setup-unsched: plain odp queue creation failed!";
1082 const char **err_str)
1086 q_elem->
priority = (uint8_t)setup->prio;
1103 const char **err_str)
1107 uint32_t nbr_output_queues;
1109 nbr_output_queues = env_atomic32_add_return(&
em_shm->queue_tbl.output_queue_count, 1);
1112 *err_str =
"Q-setup-output: too many output queues";
1122 q_elem->
state = EM_QUEUE_STATE_UNSCHEDULED;
1124 if (unlikely(output_conf->
output_fn == NULL)) {
1125 *err_str =
"Q-setup-output: invalid output function";
1129 env_spinlock_lock(&
em_shm->queue_tbl.output_queue_lock);
1131 if (
em_shm->queue_tbl.output_queue_idx_free[i]) {
1132 em_shm->queue_tbl.output_queue_idx_free[i] =
false;
1133 q_elem->output.
idx = i;
1137 env_spinlock_unlock(&
em_shm->queue_tbl.output_queue_lock);
1146 em_event_t args_event;
1153 *err_str =
"Q-setup-output: alloc output_fn_args fails";
1164 env_spinlock_init(&q_elem->output.
lock);
1172 odp_queue_param_t odp_queue_param;
1174 const odp_queue_capability_t *odp_queue_capa =
1175 &
em_shm->queue_tbl.odp_queue_capability;
1178 odp_queue_param_init(&odp_queue_param);
1180 queue_setup_odp_common(setup, &odp_queue_param);
1182 odp_queue_param.type = ODP_QUEUE_TYPE_PLAIN;
1183 odp_queue_param.order = ODP_QUEUE_ORDER_KEEP;
1186 if (odp_queue_param.nonblocking == ODP_NONBLOCKING_LF &&
1187 odp_queue_capa->plain.lockfree.max_num == 0) {
1188 *err_str =
"Q-setup-output: non-blocking, lock-free unsched queues unavailable";
1191 if (odp_queue_param.nonblocking == ODP_NONBLOCKING_WF &&
1192 odp_queue_capa->plain.waitfree.max_num == 0) {
1193 *err_str =
"Q-setup-output: non-blocking, wait-free unsched queues unavailable";
1198 odp_queue_param.deq_mode = ODP_QUEUE_OP_MT_UNSAFE;
1201 odp_queue_param.context = NULL;
1203 int err = create_odp_queue(q_elem, &odp_queue_param);
1205 if (unlikely(err)) {
1206 *err_str =
"Q-setup-output: plain odp queue creation failed!";
1233 uint32_t state_diff;
1236 state_diff = new_state - old_state;
1238 state_diff = old_state - new_state;
1251 if (new_state == old_state &&
1257 if (unlikely(err !=
EM_OK))
1260 q_elem->
state = new_state;
1270 em_status_t err = queue_state_set(q_elem, new_state);
1273 "EM-Q:%" PRI_QUEUE " inv. state: %d=>%d",
1292 env_spinlock_lock(&eo_elem->
lock);
1294 list_for_each(&eo_elem->
queue_list, pos, list_node) {
1295 q_elem = list_node_to_queue_elem(list_node);
1296 err = queue_state_set(q_elem, new_state);
1297 if (unlikely(err !=
EM_OK))
1301 env_spinlock_unlock(&eo_elem->
lock);
1303 if (unlikely(err !=
EM_OK)) {
1304 uint32_t queue_u32 = q_elem ? q_elem->
queue : 0;
1308 "EM-Q:%" PRIx32
" inv. state: %d=>%d",
1309 queue_u32, state, new_state);
1330 "queue_state_change()->READY fails EM-Q:%" PRI_QUEUE "",
1350 "queue_state_change_all()->READY fails EO:%" PRI_EO "",
1371 "queue_state_change()->BIND fails, Q:%" PRI_QUEUE "",
1391 "queue_state_change_all()->BIND: EO:%" PRI_EO "",
1397 void print_queue_elem_info(
void)
1399 EM_PRINT(
"queue-elem size: %zu B\n",
1402 EM_DBG(
"\t\toffset\tsize\n"
1403 "\t\t------\t----\n"
1404 "valid_check:\t%3zu B\t%2zu B\n"
1405 "flags:\t\t%3zu B\t%2zu B\n"
1406 "state:\t\t%3zu B\t%2zu B\n"
1407 "priority:\t%3zu B\t%2zu B\n"
1408 "type:\t\t%3zu B\t%2zu B\n"
1409 "max_events:\t%3zu B\t%2zu B\n"
1410 "eo:\t\t%3zu B\t%2zu B\n"
1411 "queue:\t\t%3zu B\t%2zu B\n"
1412 "odp_queue:\t%3zu B\t%2zu B\n"
1413 "context:\t%3zu B\t%2zu B\n"
1415 " rcv_fn:\t%3zu B\t%2zu B\n"
1416 " rcv_multi_fn:\t%3zu B\t%2zu B\n"
1418 "eo_ctx:\t\t%3zu B\t%2zu B\n"
1420 " agrp {\t%3zu B\t%2zu B\n"
1421 " .atomic_grp:\t%3zu B\t%2zu B\n"
1422 " .agrp_node:\t%3zu B\t%2zu B\n"
1424 " output {\t%3zu B\t%2zu B\n"
1425 " .conf:\t%3zu B\t%2zu B\n"
1426 " .args_event:\t%3zu B\t%2zu B\n"
1427 " .idx:\t%3zu B\t%2zu B\n"
1428 " .lock:\t%3zu B\t%2zu B\n"
1431 "eo_elem:\t%3zu B\t%2zu B\n"
1432 "queue_group:\t%3zu B\t%2zu B\n"
1433 "queue_node:\t%3zu B\t%2zu B\n"
1434 "qgrp_node:\t%3zu B\t%2zu B\n"
1435 "queue_pool_elem:%3zu B\t%2zu B\n"
1436 "end:\t\t%3zu B\t%2zu B\n",
1459 sizeof_field(
queue_elem_t, output.output_fn_args_event),
1474 const odp_queue_capability_t *queue_capa =
1475 &
em_shm->queue_tbl.odp_queue_capability;
1476 const odp_schedule_capability_t *sched_capa =
1477 &
em_shm->queue_tbl.odp_schedule_capability;
1478 char plain_sz[24] =
"n/a";
1479 char plain_lf_sz[24] =
"n/a";
1480 char plain_wf_sz[24] =
"n/a";
1481 char sched_sz[24] =
"nolimit";
1482 const unsigned int max_queues =
em_shm->opt.queue.max_num;
1487 if (queue_capa->plain.max_size > 0)
1488 snprintf(plain_sz,
sizeof(plain_sz),
"%u",
1489 queue_capa->plain.max_size);
1490 if (queue_capa->plain.lockfree.max_size > 0)
1491 snprintf(plain_lf_sz,
sizeof(plain_lf_sz),
"%u",
1492 queue_capa->plain.lockfree.max_size);
1493 if (queue_capa->plain.waitfree.max_size > 0)
1494 snprintf(plain_wf_sz,
sizeof(plain_wf_sz),
"%u",
1495 queue_capa->plain.waitfree.max_size);
1497 if (sched_capa->max_queue_size > 0)
1498 snprintf(sched_sz,
sizeof(sched_sz),
"%u",
1499 sched_capa->max_queue_size);
1501 plain_sz[
sizeof(plain_sz) - 1] =
'\0';
1502 plain_lf_sz[
sizeof(plain_lf_sz) - 1] =
'\0';
1503 plain_wf_sz[
sizeof(plain_wf_sz) - 1] =
'\0';
1504 sched_sz[
sizeof(sched_sz) - 1] =
'\0';
1506 EM_PRINT(
"ODP Queue Capabilities\n"
1507 "----------------------\n"
1508 " Max number of ODP queues: %u\n"
1509 " Max number of ODP ordered locks per queue: %u\n"
1510 " Max number of ODP scheduling groups: %u\n"
1511 " Max number of ODP scheduling priorities: %u\n"
1513 " blocking: count: %6u size: %6s\n"
1514 " nonblocking-lf: count: %6u size: %6s\n"
1515 " nonblocking-wf: count: %6u size: %6s\n"
1517 " blocking: count: %6u size: %6s\n"
1518 " nonblocking-lf: %ssupported\n"
1519 " nonblocking-wf: %ssupported\n\n",
1520 queue_capa->max_queues, sched_capa->max_ordered_locks,
1521 sched_capa->max_groups, sched_capa->max_prios,
1522 queue_capa->plain.max_num, plain_sz,
1523 queue_capa->plain.lockfree.max_num, plain_lf_sz,
1524 queue_capa->plain.waitfree.max_num, plain_wf_sz,
1525 sched_capa->max_queues, sched_sz,
1526 sched_capa->lockfree_queues == ODP_SUPPORT_NO ?
"not " :
"",
1527 sched_capa->waitfree_queues == ODP_SUPPORT_NO ?
"not " :
"");
1529 EM_PRINT(
"EM Queues\n"
1531 " Max number of EM queues: %d (0x%x)\n"
1532 " EM queue handle offset: %d (0x%x)\n"
1533 " EM queue range: [%d - %d] ([0x%x - 0x%x])\n"
1534 " static range: [%d - %d] ([0x%x - 0x%x])\n"
1535 " internal range: [%d - %d] ([0x%x - 0x%x])\n"
1536 " dynamic range: [%d - %d] ([0x%x - 0x%x])\n"
1538 max_queues, max_queues,
1544 FIRST_INTERNAL_QUEUE, LAST_INTERNAL_QUEUE,
1545 FIRST_INTERNAL_QUEUE, LAST_INTERNAL_QUEUE,
1546 FIRST_DYN_QUEUE, last_dyn_queue,
1547 FIRST_DYN_QUEUE, last_dyn_queue);
1550 void print_queue_prio_info(
void)
1552 #define MAXPRIOBUF 128
1553 char buf[MAXPRIOBUF];
1558 int num = snprintf(&buf[pos], MAXPRIOBUF - pos,
"%d%c",
1561 if (num < 0 || num >= (MAXPRIOBUF - pos))
1566 buf[MAXPRIOBUF - 1] = 0;
1567 EM_PRINT(
" Current queue priority map: [%s]\n", buf);
1573 return env_atomic32_get(&
em_shm->queue_count);
1576 size_t queue_get_name(
const queue_elem_t *
const q_elem,
1577 char name[],
const size_t maxlen)
1579 em_queue_t queue = (em_queue_t)(uintptr_t)q_elem->
queue;
1580 const char *queue_name = &
em_shm->queue_tbl.name[queue_hdl2idx(queue)][0];
1583 if (maxlen - 1 < len)
1587 memcpy(name, queue_name, len);
1593 static void queue_init_prio_legacy(
int minp,
int maxp)
1597 int def = odp_schedule_default_prio();
1601 "queue_prio_e values / EM_QUEUE_PRIO_NUM mismatch!\n");
1616 static void queue_init_prio_adaptive(
int minp,
int maxp,
int nump)
1619 double cur = (double)minp;
1633 static int queue_init_prio_custom(
int minp,
int maxp)
1645 static int queue_init_prio_map(
int minp,
int maxp,
int nump)
1651 switch (
em_shm->opt.queue.priority.map_mode) {
1653 queue_init_prio_legacy(minp, maxp);
1656 queue_init_prio_adaptive(minp, maxp, nump);
1659 if (queue_init_prio_custom(minp, maxp) != 0)
1663 EM_PRINT(
"Unknown map_mode %d!\n",
em_shm->opt.queue.priority.map_mode);
1667 EM_PRINT(
" EM uses %d priorities, runtime %d (%d-%d)\n",
1669 print_queue_prio_info();
1690 case EM_QUEUE_STATE_UNSCHEDULED:
1703 const char *type_str;
1710 type_str =
"ATOMIC";
1713 type_str =
"PARALLEL";
1716 type_str =
"ORDERED";
1725 type_str =
"OUTPUT";
1728 type_str =
"UNKNOWN";
1735 #define QUEUE_INFO_HDR_STR \
1736 "Number of queues: %d\n\n" \
1737 "Handle Name Priority Type State Qgrp" \
1738 " Agrp EO Multi-rcv Max-events Ctx\n" \
1739 "---------------------------------------------------------------------------" \
1740 "----------------------------------------------------\n" \
1743 #define QUEUE_INFO_LEN 128
1745 #define QUEUE_INFO_FMT \
1746 "%-10" PRI_QUEUE "%-32s%-10" PRI_QPRIO "%-10s%-9s%-10" PRI_QGRP "%-10" PRI_AGRP \
1747 "%-10" PRI_EO "%-11c%-12d%-3c\n"
1765 const int q_info_buf_len = (q_num + 10) * QUEUE_INFO_LEN + 1;
1766 char q_info_buf[q_info_buf_len];
1769 q_elem = queue_elem_get(q);
1771 if (unlikely(q_elem == NULL || !queue_allocated(q_elem))) {
1777 em_eo_t eo = (em_eo_t)(uintptr_t)q_elem->
eo;
1783 n_print = snprintf(q_info_buf + len,
1784 q_info_buf_len - len,
1790 q_elem->flags.use_multi_rcv ?
'Y' :
'N',
1795 if (n_print >= q_info_buf_len - len)
1804 EM_PRINT(
"No EM queue!\n");
1812 q_info_buf[len] =
'\0';
1813 EM_PRINT(QUEUE_INFO_HDR_STR, q_num, q_info_buf);