42 const uint32_t objpool_subpools = MIN(4, OBJSUBPOOLS_MAX);
50 em_atomic_group_t agrp = agrp_idx2hdl(i);
52 atomic_group_elem_get(agrp);
54 if (unlikely(!agrp_elem))
60 env_spinlock_init(&agrp_elem->lock);
65 ret = objpool_init(&atomic_group_pool->objpool, objpool_subpools);
70 atomic_group_elem = &atomic_group_tbl->
ag_elem[i];
71 objpool_add(&atomic_group_pool->objpool, i % objpool_subpools,
79 ag_pool_elem2ag_elem(
const objpool_elem_t *
const atomic_group_pool_elem)
94 ag_p_elem = objpool_rem(&
em_shm->atomic_group_pool.objpool,
97 if (unlikely(ag_p_elem == NULL))
100 ag_elem = ag_pool_elem2ag_elem(ag_p_elem);
107 atomic_group_free(em_atomic_group_t atomic_group)
111 if (unlikely(agrp_elem == NULL))
114 objpool_add(&
em_shm->atomic_group_pool.objpool,
131 em_atomic_group_t atomic_group = q_elem->agrp.
atomic_group;
133 if (!invalid_atomic_group(atomic_group)) {
135 atomic_group_elem_get(atomic_group);
137 atomic_group_rem_queue_list(ag_elem, q_elem);
144 atomic_group_count(
void)
164 if (env_spinlock_trylock(&ag_elem->lock))
175 odp_event_t odp_evtbl[],
const int num_events,
182 const em_queue_t queue = (em_queue_t)(uintptr_t)q_elem->
queue;
183 const uint16_t qidx = (uint16_t)queue_hdl2idx(queue);
185 for (
int i = 0; i < num_events; i++) {
186 entry_tbl[i].qidx = qidx;
187 entry_tbl[i].evptr = (uintptr_t)odp_evtbl[i];
196 ret = odp_stash_put_u64(stash, &entry_tbl[0].u64, num_events);
197 if (unlikely(ret != num_events))
198 return ret > 0 ? ret : 0;
217 &entry_tbl[0].u64 , num_events);
218 if (hi_cnt == num_events || hi_cnt < 0)
223 &entry_tbl[hi_cnt].u64 ,
224 num_events - hi_cnt);
225 if (unlikely(lo_cnt < 0))
228 return hi_cnt + lo_cnt;
231 void atomic_group_dispatch(odp_event_t odp_evtbl[],
const int num_events,
239 int enq_cnt = ag_internal_enq(ag_elem, q_elem, odp_evtbl, num_events, priority);
241 if (unlikely(enq_cnt < num_events)) {
242 int num_free = num_events - enq_cnt;
244 em_event_t ev_tbl[num_free];
246 event_init_odp_multi(&odp_evtbl[enq_cnt], ev_tbl, ev_hdr_tbl,
255 "Atomic group:%" PRI_AGRP " internal enqueue fails:\n"
256 " num_events:%d enq_cnt:%d => %d events dropped",
264 if (!env_spinlock_trylock(&ag_elem->lock))
270 odp_schedule_release_atomic();
282 int deq_cnt = ag_internal_deq(ag_elem, entry_tbl ,
285 if (unlikely(deq_cnt <= 0)) {
286 env_spinlock_unlock(&ag_elem->lock);
291 for (
int i = 0; i < deq_cnt; i++)
292 deq_evtbl[i] = (odp_event_t)(uintptr_t)entry_tbl[i].evptr;
302 const int qidx = entry_tbl[tbl_idx].qidx;
303 const em_queue_t queue = queue_idx2hdl(qidx);
304 queue_elem_t *
const batch_qelem = queue_elem_get(queue);
309 for (
int i = tbl_idx + 1; i < deq_cnt &&
310 entry_tbl[i].qidx == qidx; i++) {
314 dispatch_events(&deq_evtbl[tbl_idx],
315 batch_cnt, batch_qelem);
316 tbl_idx += batch_cnt;
317 }
while (tbl_idx < deq_cnt);
319 }
while (!ag_local_processing_ended(ag_elem));
322 #define AG_INFO_HDR_STR \
323 "Number of atomic groups: %d\n\n" \
324 "ID Name Qgrp Q-num\n" \
325 "---------------------------------------------------------\n%s\n"
327 #define AG_INFO_LEN 58
328 #define AG_INFO_FMT "%-10" PRI_AGRP "%-32s%-10" PRI_QGRP "%-5d\n"
334 em_atomic_group_t ag_check;
351 const int ag_info_str_len = (ag_num + 10) * AG_INFO_LEN + 1;
352 char ag_info_str[ag_info_str_len];
355 ag_elem = atomic_group_elem_get(ag);
360 if (unlikely(ag_elem == NULL || ag_check != ag ||
361 !atomic_group_allocated(ag_elem))) {
366 n_print = snprintf(ag_info_str + len, ag_info_str_len - len,
371 if (n_print >= ag_info_str_len - len)
380 EM_PRINT(
"No atomic group has been created\n");
388 ag_info_str[len] =
'\0';
389 EM_PRINT(AG_INFO_HDR_STR, ag_num, ag_info_str);
392 #define AG_QUEUE_INFO_HDR_STR \
393 "Atomic group %" PRI_AGRP "(%s) has %d queue(s):\n\n" \
394 "ID Name Priority Type State Qgrp Ctx\n" \
395 "-----------------------------------------------------------------------------------\n" \
398 #define AG_Q_INFO_LEN 85
399 #define AG_Q_INFO_FMT "%-10" PRI_QUEUE "%-32s%-10d%-10s%-9s%-10" PRI_QGRP "%-3c\n"
412 if (unlikely(ag_elem == NULL || !atomic_group_allocated(ag_elem))) {
413 EM_PRINT(
"Atomic group %" PRI_AGRP "is not created!\n", ag);
428 int q_info_str_len = (q_num + 10) * AG_Q_INFO_LEN + 1;
429 char q_info_str[q_info_str_len];
432 q_elem = queue_elem_get(ag_queue);
434 if (unlikely(q_elem == NULL || !queue_allocated(q_elem))) {
441 n_print = snprintf(q_info_str + len, q_info_str_len - len,
442 AG_Q_INFO_FMT, ag_queue, q_name,
450 if (n_print >= q_info_str_len - len)
459 EM_PRINT(
"Atomic group %" PRI_AGRP "(%s) has no queue!\n",
468 q_info_str[len] =
'\0';
469 EM_PRINT(AG_QUEUE_INFO_HDR_STR, ag, ag_elem->
name, q_num, q_info_str);
472 void print_ag_elem_info(
void)
477 "ag-elem size: %zu B\n",
480 EM_DBG(
"\t\toffset\tsize\n"
481 "\t\t------\t-----\n"
482 "atomic_group:\t%3zu B\t%3zu B\n"
483 "queue_group:\t%3zu B\t%3zu B\n"
484 "ag pool_elem:\t%3zu B\t%3zu B\n"
485 "stashes:\t%3zu B\t%3zu B\n"
486 "lock:\t\t%3zu B\t%3zu B\n"
487 "num_queues:\t%3zu B\t%3zu B\n"
488 "qlist_head[]:\t%3zu B\t%3zu B\n"
489 "name:\t\t%3zu B\t%3zu B\n",