EM-ODP  3.7.0
Event Machine on ODP
event_machine_atomic_group.c
1 /*
2  * Copyright (c) 2014-2023, Nokia Solutions and Networks
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * * Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "em_include.h"
32 
33 /* per core (thread) state for em_atomic_group_get_next() */
34 static ENV_LOCAL unsigned int _agrp_tbl_iter_idx;
35 /* Per core (thread) state of em_atomic_group_queue_get_next() */
36 static ENV_LOCAL unsigned int _agrp_q_iter_idx;
37 static ENV_LOCAL em_atomic_group_t _agrp_q_iter_agrp;
38 
39 em_atomic_group_t
40 em_atomic_group_create(const char *name, em_queue_group_t queue_group)
41 {
42  em_atomic_group_t atomic_group = EM_ATOMIC_GROUP_UNDEF;
43  atomic_group_elem_t *ag_elem = NULL;
44  const char *err_str = "";
45  em_status_t error = EM_OK;
46  int ret = 0;
47 
48  if (unlikely(invalid_qgrp(queue_group))) {
49  error = EM_ERR_BAD_ARG;
50  err_str = "Invalid queue group!";
51  goto error;
52  }
53 
54  /* New Atomic group */
55  atomic_group = atomic_group_alloc();
56 
57  if (unlikely(atomic_group == EM_ATOMIC_GROUP_UNDEF)) {
58  error = EM_ERR_ALLOC_FAILED;
59  err_str = "Atomic group allocation failed!";
60  goto error;
61  }
62 
63  /* Initialize the atomic group */
64  ag_elem = atomic_group_elem_get(atomic_group);
65  if (unlikely(!ag_elem)) {
66  /* Fatal since atomic_group_alloc() returned 'ok', should never happen */
67  error = EM_FATAL(EM_ERR_BAD_ID);
68  err_str = "Atomic group allocation failed: ag_elem NULL!";
69  goto error;
70  }
71 
72  env_atomic32_init(&ag_elem->num_queues);
73 
74  /* Store the related queue group */
75  ag_elem->queue_group = queue_group;
76 
77  if (name != NULL) {
78  strncpy(ag_elem->name, name, sizeof(ag_elem->name));
79  ag_elem->name[sizeof(ag_elem->name) - 1] = '\0';
80  } else {
81  ag_elem->name[0] = '\0';
82  }
83 
84  /*
85  * Create the AG internal stashes
86  */
87  unsigned int num_obj = 0;
88  odp_stash_capability_t stash_capa;
89  odp_stash_param_t stash_param;
90 
91  ret = odp_stash_capability(&stash_capa, ODP_STASH_TYPE_FIFO);
92  if (ret != 0) {
93  error = EM_ERR_LIB_FAILED;
94  err_str = "odp_stash_capability() failed!";
95  goto error;
96  }
97 
98  odp_stash_param_init(&stash_param);
99 
100  stash_param.type = ODP_STASH_TYPE_FIFO;
101  stash_param.put_mode = ODP_STASH_OP_MT;
102  /* 'get' protected by ag_elem->lock */
103  stash_param.get_mode = ODP_STASH_OP_ST;
104 
105  /* Stash size: use EM default queue size value from config file: */
106  num_obj = em_shm->opt.queue.min_events_default;
107  if (num_obj != 0)
108  stash_param.num_obj = num_obj;
109  /* else: use odp default as set by odp_stash_param_init() */
110 
111  stash_param.obj_size = sizeof(uint64_t);
112  if (stash_param.num_obj > stash_capa.max_num.u64) {
113  EM_LOG(EM_LOG_PRINT,
114  "%s(): req stash.num_obj(%" PRIu64 ") > capa.max_num.u64(%" PRIu64 ").\n"
115  " ==> using max value:%" PRIu64 "\n", __func__,
116  stash_param.num_obj, stash_capa.max_num.u64, stash_capa.max_num.u64);
117  stash_param.num_obj = stash_capa.max_num.u64;
118  }
119 
120  stash_param.cache_size = 0; /* No core local caching */
121 
122  ag_elem->stashes.hi_prio = odp_stash_create(ag_elem->name, &stash_param);
123  ag_elem->stashes.lo_prio = odp_stash_create(ag_elem->name, &stash_param);
124  if (unlikely(ag_elem->stashes.hi_prio == ODP_STASH_INVALID ||
125  ag_elem->stashes.lo_prio == ODP_STASH_INVALID)) {
126  error = EM_ERR_LIB_FAILED;
127  err_str = "odp_stash_create() failed!";
128  goto error;
129  }
130 
131  return atomic_group;
132 
133 error:
134  INTERNAL_ERROR(error, EM_ESCOPE_ATOMIC_GROUP_CREATE, err_str);
135  if (atomic_group != EM_ATOMIC_GROUP_UNDEF)
136  em_atomic_group_delete(atomic_group);
137 
138  return EM_ATOMIC_GROUP_UNDEF;
139 }
140 
141 /*
142  * Helper for em_atomic_group_delete()
143  * Flush the atomic group's internal queues and then destroy them.
144  */
145 static int
146 ag_stash_destroy(odp_stash_t stash)
147 {
149  odp_event_t odp_evtbl[EM_SCHED_AG_MULTI_MAX_BURST];
150  em_event_t ev_tbl[EM_SCHED_AG_MULTI_MAX_BURST];
152  int32_t cnt = 0;
153  bool esv_ena = esv_enabled();
154 
155  if (stash == ODP_STASH_INVALID)
156  return -1;
157 
158  do {
159  cnt = odp_stash_get_u64(stash, &entry_tbl[0].u64 /*[out]*/,
161  if (cnt <= 0)
162  break;
163  for (int32_t i = 0; i < cnt; i++)
164  odp_evtbl[i] = (odp_event_t)(uintptr_t)entry_tbl[i].evptr;
165 
166  events_odp2em(odp_evtbl, ev_tbl/*out*/, cnt);
167 
168  if (esv_ena) {
169  event_to_hdr_multi(ev_tbl, ev_hdr_tbl/*out*/, cnt);
170  evstate_em2usr_multi(ev_tbl/*in/out*/, ev_hdr_tbl,
171  cnt, EVSTATE__AG_DELETE);
172  }
173 
174  em_free_multi(ev_tbl, cnt);
175  } while (cnt > 0);
176 
177  return odp_stash_destroy(stash);
178 }
179 
181 em_atomic_group_delete(em_atomic_group_t atomic_group)
182 {
183  atomic_group_elem_t *const ag_elem =
184  atomic_group_elem_get(atomic_group);
185  em_status_t error = EM_OK;
186  int err = 0;
187 
188  RETURN_ERROR_IF(ag_elem == NULL,
189  EM_ERR_BAD_ARG, EM_ESCOPE_ATOMIC_GROUP_DELETE,
190  "Invalid atomic group - cannot delete!");
191 
192  env_spinlock_lock(&ag_elem->lock);
193 
194  /* Error checks */
195  err = !list_is_empty(&ag_elem->qlist_head);
196  err |= !atomic_group_allocated(ag_elem);
197 
198  if (unlikely(err)) {
199  env_spinlock_unlock(&ag_elem->lock);
201  EM_ESCOPE_ATOMIC_GROUP_DELETE,
202  "Atomic group in bad state - cannot delete!");
203  }
204 
205  /* Flush the atomic group's internal queues and destroy them */
206  err = ag_stash_destroy(ag_elem->stashes.hi_prio);
207  err |= ag_stash_destroy(ag_elem->stashes.lo_prio);
208 
210  ag_elem->name[0] = '\0';
211 
212  env_spinlock_unlock(&ag_elem->lock);
213 
214  /* Free the atomic group (elem) back into the AG-pool */
215  error = atomic_group_free(atomic_group);
216  RETURN_ERROR_IF(error != EM_OK || err != 0,
217  error, EM_ESCOPE_ATOMIC_GROUP_DELETE,
218  "Atomic group free failed(%d)!", err);
219 
220  return EM_OK;
221 }
222 
223 em_queue_t
224 em_queue_create_ag(const char *name, em_queue_prio_t prio,
225  em_atomic_group_t atomic_group, const em_queue_conf_t *conf)
226 {
227  em_queue_t queue;
228  queue_elem_t *q_elem;
229  em_queue_group_t queue_group;
230  atomic_group_elem_t *const ag_elem =
231  atomic_group_elem_get(atomic_group);
232  const char *err_str = "";
233 
234  if (unlikely(!ag_elem || !atomic_group_allocated(ag_elem))) {
235  INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_QUEUE_CREATE_AG,
236  "Invalid Atomic Group:%" PRI_AGRP "",
237  atomic_group);
238  return EM_QUEUE_UNDEF;
239  }
240 
241  queue_group = ag_elem->queue_group;
242 
243  queue = queue_create(name, EM_QUEUE_TYPE_ATOMIC, prio, queue_group,
244  EM_QUEUE_UNDEF, atomic_group, conf, &err_str);
245 
246  if (unlikely(queue == EM_QUEUE_UNDEF)) {
247  INTERNAL_ERROR(EM_ERR_LIB_FAILED, EM_ESCOPE_QUEUE_CREATE_AG,
248  "Atomic Group queue creation failed! (%s)",
249  err_str);
250  return EM_QUEUE_UNDEF;
251  }
252 
253  q_elem = queue_elem_get(queue);
254  if (unlikely(!q_elem)) {
255  INTERNAL_ERROR(EM_ERR_BAD_POINTER, EM_ESCOPE_QUEUE_CREATE_AG,
256  "Atomic Group Q:%" PRI_QUEUE " - q_elem = NULL",
257  queue);
258  queue_free(queue);
259  return EM_QUEUE_UNDEF;
260  }
261 
262  /* Add queue to atomic group list */
263  atomic_group_add_queue_list(ag_elem, q_elem);
264 
265  return queue;
266 }
267 
270  em_atomic_group_t atomic_group, em_queue_t queue,
271  const em_queue_conf_t *conf)
272 {
273  em_queue_t queue_static;
274  em_queue_group_t queue_group;
275  atomic_group_elem_t *const ag_elem =
276  atomic_group_elem_get(atomic_group);
277  const char *err_str = "";
278 
279  RETURN_ERROR_IF(!ag_elem || !atomic_group_allocated(ag_elem),
280  EM_ERR_BAD_ARG, EM_ESCOPE_QUEUE_CREATE_STATIC_AG,
281  "Invalid Atomic Group:%" PRI_AGRP "", atomic_group);
282 
283  queue_group = ag_elem->queue_group;
284 
285  queue_static = queue_create(name, EM_QUEUE_TYPE_ATOMIC, prio,
286  queue_group, queue, atomic_group, conf,
287  &err_str);
288 
289  RETURN_ERROR_IF(queue_static == EM_QUEUE_UNDEF,
290  EM_ERR_NOT_FREE, EM_ESCOPE_QUEUE_CREATE_STATIC_AG,
291  "Atomic Group static queue:%" PRI_QUEUE " creation failed! (%s)",
292  queue, err_str);
293 
294  queue_elem_t *q_elem = queue_elem_get(queue_static);
295 
296  /* Fatal error if q_elem == NULL, should never happen if queue_static != UNDEF */
297  RETURN_ERROR_IF(!q_elem, EM_FATAL(EM_ERR_BAD_POINTER),
298  EM_ESCOPE_QUEUE_CREATE_STATIC_AG,
299  "Queue elem NULL - req:%" PRI_QUEUE " vs. %" PRI_QUEUE "(=NULL)",
300  queue, queue_static);
301 
302  if (unlikely(queue_static != queue)) {
303  queue_delete(q_elem);
304  return INTERNAL_ERROR(EM_ERR_BAD_ID, EM_ESCOPE_QUEUE_CREATE_STATIC_AG,
305  "Queue error - req:%" PRI_QUEUE " vs. %" PRI_QUEUE "",
306  queue, queue_static);
307  }
308 
309  /* Add queue to atomic group list */
310  atomic_group_add_queue_list(ag_elem, q_elem);
311 
312  return EM_OK;
313 }
314 
315 em_atomic_group_t
316 em_atomic_group_get(em_queue_t queue)
317 {
318  const queue_elem_t *q_elem = queue_elem_get(queue);
319  em_atomic_group_t atomic_group = EM_ATOMIC_GROUP_UNDEF;
320 
321  if (unlikely(q_elem == NULL || !queue_allocated(q_elem))) {
322  INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_ATOMIC_GROUP_GET,
323  "Invalid queue:%" PRI_QUEUE "", queue);
324  return EM_ATOMIC_GROUP_UNDEF;
325  }
326 
327  if (q_elem->flags.in_atomic_group)
328  atomic_group = q_elem->agrp.atomic_group;
329 
330  return atomic_group;
331 }
332 
333 size_t
334 em_atomic_group_get_name(em_atomic_group_t atomic_group,
335  char *name, size_t maxlen)
336 {
337  const atomic_group_elem_t *ag_elem =
338  atomic_group_elem_get(atomic_group);
339  size_t len = 0;
340 
341  if (unlikely(name == NULL || maxlen == 0)) {
342  INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_ATOMIC_GROUP_GET_NAME,
343  "Invalid args: name=0x%" PRIx64 ", maxlen=%zu",
344  name, maxlen);
345  return 0;
346  }
347 
348  if (unlikely(ag_elem == NULL || !atomic_group_allocated(ag_elem))) {
349  INTERNAL_ERROR(EM_ERR_BAD_ARG, EM_ESCOPE_ATOMIC_GROUP_GET_NAME,
350  "Invalid Atomic Group:%" PRI_AGRP "",
351  atomic_group);
352  name[0] = '\0';
353  return 0;
354  }
355 
356  len = strnlen(ag_elem->name, sizeof(ag_elem->name) - 1);
357  if (maxlen - 1 < len)
358  len = maxlen - 1;
359 
360  memcpy(name, ag_elem->name, len);
361  name[len] = '\0';
362 
363  return len;
364 }
365 
366 em_atomic_group_t
367 em_atomic_group_find(const char *name)
368 {
369  if (name && *name) {
370  for (int i = 0; i < EM_MAX_ATOMIC_GROUPS; i++) {
371  const atomic_group_elem_t *ag_elem =
372  &em_shm->atomic_group_tbl.ag_elem[i];
373 
374  if (atomic_group_allocated(ag_elem) &&
375  !strncmp(name, ag_elem->name,
377  return ag_elem->atomic_group;
378  }
379  }
380  return EM_ATOMIC_GROUP_UNDEF;
381 }
382 
383 em_atomic_group_t
384 em_atomic_group_get_first(unsigned int *num)
385 {
386  const atomic_group_elem_t *const agrp_elem_tbl =
387  em_shm->atomic_group_tbl.ag_elem;
388  const atomic_group_elem_t *ag_elem = &agrp_elem_tbl[0];
389  const unsigned int agrp_count = atomic_group_count();
390 
391  _agrp_tbl_iter_idx = 0; /* reset iteration */
392 
393  if (num)
394  *num = agrp_count;
395 
396  if (agrp_count == 0) {
397  _agrp_tbl_iter_idx = EM_MAX_ATOMIC_GROUPS; /*UNDEF=_get_next()*/
398  return EM_ATOMIC_GROUP_UNDEF;
399  }
400 
401  /* find first */
402  while (!atomic_group_allocated(ag_elem)) {
403  _agrp_tbl_iter_idx++;
404  if (_agrp_tbl_iter_idx >= EM_MAX_ATOMIC_GROUPS)
405  return EM_ATOMIC_GROUP_UNDEF;
406  ag_elem = &agrp_elem_tbl[_agrp_tbl_iter_idx];
407  }
408 
409  return agrp_idx2hdl(_agrp_tbl_iter_idx);
410 }
411 
412 em_atomic_group_t
414 {
415  if (_agrp_tbl_iter_idx >= EM_MAX_ATOMIC_GROUPS - 1)
416  return EM_ATOMIC_GROUP_UNDEF;
417 
418  _agrp_tbl_iter_idx++;
419 
420  const atomic_group_elem_t *const agrp_elem_tbl =
421  em_shm->atomic_group_tbl.ag_elem;
422  const atomic_group_elem_t *ag_elem = &agrp_elem_tbl[_agrp_tbl_iter_idx];
423 
424  /* find next */
425  while (!atomic_group_allocated(ag_elem)) {
426  _agrp_tbl_iter_idx++;
427  if (_agrp_tbl_iter_idx >= EM_MAX_ATOMIC_GROUPS)
428  return EM_ATOMIC_GROUP_UNDEF;
429  ag_elem = &agrp_elem_tbl[_agrp_tbl_iter_idx];
430  }
431 
432  return agrp_idx2hdl(_agrp_tbl_iter_idx);
433 }
434 
435 em_queue_t
437  em_atomic_group_t atomic_group)
438 {
439  const atomic_group_elem_t *const agrp_elem =
440  atomic_group_elem_get(atomic_group);
441 
442  const unsigned int max_queues = em_shm->opt.queue.max_num;
443 
444  if (unlikely(agrp_elem == NULL || !atomic_group_allocated(agrp_elem))) {
446  EM_ESCOPE_ATOMIC_GROUP_QUEUE_GET_FIRST,
447  "Invalid atomic group:%" PRI_AGRP "",
448  atomic_group);
449  if (num)
450  *num = 0;
451  return EM_QUEUE_UNDEF;
452  }
453 
454  const unsigned int num_queues =
455  env_atomic32_get(&agrp_elem->num_queues);
456 
457  if (num)
458  *num = num_queues;
459 
460  if (num_queues == 0) {
461  _agrp_q_iter_idx = max_queues; /* UNDEF = _get_next() */
462  return EM_QUEUE_UNDEF;
463  }
464 
465  /*
466  * A 'agrp_elem' contains a linked list with all it's queues. That list
467  * might be modified while processing this iteration, so instead we just
468  * go through the whole queue table.
469  * This is potentially a slow implementation and perhaps worth
470  * re-thinking?
471  */
472  const queue_elem_t *const q_elem_tbl = em_shm->queue_tbl.queue_elem;
473  const queue_elem_t *q_elem = &q_elem_tbl[0];
474 
475  _agrp_q_iter_idx = 0; /* reset list */
476  _agrp_q_iter_agrp = atomic_group;
477 
478  /* find first */
479  while (!queue_allocated(q_elem) ||
480  !q_elem->flags.in_atomic_group ||
481  q_elem->agrp.atomic_group != _agrp_q_iter_agrp) {
482  _agrp_q_iter_idx++;
483  if (_agrp_q_iter_idx >= max_queues)
484  return EM_QUEUE_UNDEF;
485  q_elem = &q_elem_tbl[_agrp_q_iter_idx];
486  }
487 
488  return queue_idx2hdl(_agrp_q_iter_idx);
489 }
490 
491 em_queue_t
493 {
494  const unsigned int max_queues = em_shm->opt.queue.max_num;
495 
496  if (_agrp_q_iter_idx >= max_queues - 1)
497  return EM_QUEUE_UNDEF;
498 
499  _agrp_q_iter_idx++;
500 
501  const queue_elem_t *const q_elem_tbl = em_shm->queue_tbl.queue_elem;
502  const queue_elem_t *q_elem = &q_elem_tbl[_agrp_q_iter_idx];
503 
504  /* find next */
505  while (!queue_allocated(q_elem) ||
506  !q_elem->flags.in_atomic_group ||
507  q_elem->agrp.atomic_group != _agrp_q_iter_agrp) {
508  _agrp_q_iter_idx++;
509  if (_agrp_q_iter_idx >= max_queues)
510  return EM_QUEUE_UNDEF;
511  q_elem = &q_elem_tbl[_agrp_q_iter_idx];
512  }
513 
514  return queue_idx2hdl(_agrp_q_iter_idx);
515 }
516 
517 uint64_t em_atomic_group_to_u64(em_atomic_group_t atomic_group)
518 {
519  return (uint64_t)atomic_group;
520 }
EM_SCHED_AG_MULTI_MAX_BURST
#define EM_SCHED_AG_MULTI_MAX_BURST
Definition: event_machine_hw_config.h:232
EM_QUEUE_GROUP_UNDEF
#define EM_QUEUE_GROUP_UNDEF
Definition: event_machine_types.h:127
em_atomic_group_get_next
em_atomic_group_t em_atomic_group_get_next(void)
Definition: event_machine_atomic_group.c:413
EM_OK
#define EM_OK
Definition: event_machine_types.h:329
atomic_group_elem_t::hi_prio
odp_stash_t hi_prio
Definition: em_atomic_group_types.h:56
atomic_group_elem_t::qlist_head
list_node_t qlist_head
Definition: em_atomic_group_types.h:67
em_queue_conf_t
Definition: event_machine_types.h:212
atomic_group_elem_t::num_queues
env_atomic32_t num_queues
Definition: em_atomic_group_types.h:64
atomic_group_alloc
em_atomic_group_t atomic_group_alloc(void)
Definition: em_atomic_group.c:89
em_atomic_group_find
em_atomic_group_t em_atomic_group_find(const char *name)
Definition: event_machine_atomic_group.c:367
em_queue_create_static_ag
em_status_t em_queue_create_static_ag(const char *name, em_queue_prio_t prio, em_atomic_group_t atomic_group, em_queue_t queue, const em_queue_conf_t *conf)
Definition: event_machine_atomic_group.c:269
stash_entry_t
Definition: em_event_types.h:86
EM_ERR_ALLOC_FAILED
@ EM_ERR_ALLOC_FAILED
Definition: event_machine_hw_types.h:287
EM_ERR_LIB_FAILED
@ EM_ERR_LIB_FAILED
Definition: event_machine_hw_types.h:291
atomic_group_elem_t::stashes
struct atomic_group_elem_t::@15 stashes
em_atomic_group_get_first
em_atomic_group_t em_atomic_group_get_first(unsigned int *num)
Definition: event_machine_atomic_group.c:384
EM_QUEUE_TYPE_ATOMIC
@ EM_QUEUE_TYPE_ATOMIC
Definition: event_machine_hw_types.h:112
EM_MAX_ATOMIC_GROUPS
#define EM_MAX_ATOMIC_GROUPS
Definition: event_machine_config.h:137
em_atomic_group_to_u64
uint64_t em_atomic_group_to_u64(em_atomic_group_t atomic_group)
Definition: event_machine_atomic_group.c:517
PRI_AGRP
#define PRI_AGRP
Definition: event_machine_types.h:158
event_hdr
Definition: em_event_types.h:184
em_atomic_group_queue_get_next
em_queue_t em_atomic_group_queue_get_next(void)
Definition: event_machine_atomic_group.c:492
EM_ERR_NOT_FREE
@ EM_ERR_NOT_FREE
Definition: event_machine_hw_types.h:276
atomic_group_elem_t
Definition: em_atomic_group_types.h:46
RETURN_ERROR_IF
#define RETURN_ERROR_IF(cond, error, escope, fmt,...)
Definition: em_error.h:50
em_atomic_group_create
em_atomic_group_t em_atomic_group_create(const char *name, em_queue_group_t queue_group)
Definition: event_machine_atomic_group.c:40
atomic_group_elem_t::queue_group
em_queue_group_t queue_group
Definition: em_atomic_group_types.h:50
EM_ERR_BAD_ID
@ EM_ERR_BAD_ID
Definition: event_machine_hw_types.h:265
INTERNAL_ERROR
#define INTERNAL_ERROR(error, escope, fmt,...)
Definition: em_error.h:43
queue_elem_t::in_atomic_group
uint8_t in_atomic_group
Definition: em_queue_types.h:201
EM_ATOMIC_GROUP_NAME_LEN
#define EM_ATOMIC_GROUP_NAME_LEN
Definition: event_machine_config.h:143
queue_delete
em_status_t queue_delete(queue_elem_t *const queue_elem)
Definition: em_queue.c:652
queue_create
em_queue_t queue_create(const char *name, em_queue_type_t type, em_queue_prio_t prio, em_queue_group_t queue_group, em_queue_t queue_req, em_atomic_group_t atomic_group, const em_queue_conf_t *conf, const char **err_str)
Definition: em_queue.c:592
em_status_t
uint32_t em_status_t
Definition: event_machine_types.h:321
PRI_QUEUE
#define PRI_QUEUE
Definition: event_machine_types.h:109
em_atomic_group_queue_get_first
em_queue_t em_atomic_group_queue_get_first(unsigned int *num, em_atomic_group_t atomic_group)
Definition: event_machine_atomic_group.c:436
em_atomic_group_get_name
size_t em_atomic_group_get_name(em_atomic_group_t atomic_group, char *name, size_t maxlen)
Definition: event_machine_atomic_group.c:334
EM_ATOMIC_GROUP_UNDEF
#define EM_ATOMIC_GROUP_UNDEF
Definition: event_machine_types.h:156
em_shm
em_shm_t * em_shm
Definition: event_machine_init.c:41
atomic_group_elem_t::atomic_group
em_atomic_group_t atomic_group
Definition: em_atomic_group_types.h:48
EM_QUEUE_UNDEF
#define EM_QUEUE_UNDEF
Definition: event_machine_types.h:107
em_include.h
atomic_group_elem_t::name
char name[EM_ATOMIC_GROUP_NAME_LEN]
Definition: em_atomic_group_types.h:69
em_atomic_group_delete
em_status_t em_atomic_group_delete(em_atomic_group_t atomic_group)
Definition: event_machine_atomic_group.c:181
evstate_em2usr_multi
void evstate_em2usr_multi(em_event_t ev_tbl[], event_hdr_t *const ev_hdr_tbl[], const int num, const uint16_t api_op)
Definition: em_event_state.c:970
EM_ERR_BAD_POINTER
@ EM_ERR_BAD_POINTER
Definition: event_machine_hw_types.h:271
em_queue_prio_t
uint32_t em_queue_prio_t
Definition: event_machine_types.h:186
em_queue_create_ag
em_queue_t em_queue_create_ag(const char *name, em_queue_prio_t prio, em_atomic_group_t atomic_group, const em_queue_conf_t *conf)
Definition: event_machine_atomic_group.c:224
EM_ERR_BAD_ARG
@ EM_ERR_BAD_ARG
Definition: event_machine_hw_types.h:261
q_elem_atomic_group_::atomic_group
em_atomic_group_t atomic_group
Definition: em_queue_types.h:158
em_free_multi
void em_free_multi(em_event_t events[], int num)
Definition: event_machine_event.c:370
ENV_LOCAL
#define ENV_LOCAL
Definition: environment.h:57
EM_ERR_BAD_STATE
@ EM_ERR_BAD_STATE
Definition: event_machine_hw_types.h:263
queue_elem_t
Definition: em_queue_types.h:180
em_atomic_group_get
em_atomic_group_t em_atomic_group_get(em_queue_t queue)
Definition: event_machine_atomic_group.c:316
atomic_group_elem_t::lo_prio
odp_stash_t lo_prio
Definition: em_atomic_group_types.h:58