EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
event_machine_atomic_group.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014-2026, 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#ifndef EVENT_MACHINE_ATOMIC_GROUP_H_
32#define EVENT_MACHINE_ATOMIC_GROUP_H_
33
34#pragma GCC visibility push(default)
35
36/**
37 * @file
38 * @defgroup em_atomic_group Atomic group
39 * Event Machine atomic queue group (new to API 1.1)
40 * @{
41 *
42 * An atomic group combines multiple atomic queues in such a way that only one
43 * event from any of the included queues can be scheduled to the application at
44 * any one time, effectively scheduling several queues like a single atomic one.
45 * The main use case is to provide a protected race free context by atomic
46 * scheduling but allow multiple priorities (all of the queue contexts for
47 * queues in one atomic group are protected. The related EO context is also
48 * protected, if all queues of that EO are in one atomic group only, thus
49 * effectively creating an atomic EO).
50 *
51 * All queues in an atomic group belong to the same queue group given when
52 * creating a new atomic group. Queues for an atomic group must be created
53 * using _ag - functions, but can be deleted normally using em_queue_delete().
54 */
55
59
60#ifdef __cplusplus
61extern "C" {
62#endif
63
64/**
65 * Create a new atomic group
66 *
67 * Some systems may have a limited number of atomic groups available or a
68 * limited number of queues per atomic group.
69 *
70 * The given name string is copied into an EM internal data structure. The
71 * maximum string length is EM_ATOMIC_GROUP_NAME_LEN. Duplicate names are
72 * allowed, but find will only match one of them.
73 *
74 * @param name Atomic group name (optional, NULL ok)
75 * @param queue_group Existing queue group to use for this atomic group
76 *
77 * @return Atomic group or EM_ATOMIC_GROUP_UNDEF on error.
78 */
79em_atomic_group_t
80em_atomic_group_create(const char *name, em_queue_group_t queue_group);
81
82/**
83 * Delete an atomic group.
84 *
85 * @attention An atomic group can only be deleted after all queues belonging
86 * to it have been removed from the EOs and deleted.
87 *
88 * @param atomic_group Atomic group to delete
89 *
90 * @return EM_OK if successful.
91 *
92 * @see em_atomic_group_create()
93 */
94em_status_t em_atomic_group_delete(em_atomic_group_t atomic_group);
95
96/**
97 * Create a new queue with a dynamic queue handle belonging to an atomic group.
98 *
99 * Queues created with this are always of type EM_QUEUE_TYPE_ATOMIC.
100 *
101 * The given name string is copied to EM internal data structure. The maximum
102 * string length is EM_QUEUE_NAME_LEN.
103 *
104 * The 'conf' argument is optional and can be used to pass extra attributes
105 * (e.g. require non-blocking behaviour, if supported) to the system specific
106 * implementation.
107 *
108 * @param name Queue name (optional, NULL ok)
109 * @param prio Queue priority
110 * @param atomic_group Existing atomic group for this queue
111 * @param conf Optional configuration data, NULL for defaults
112 *
113 * @return New queue handle or EM_QUEUE_UNDEF on an error.
114 *
115 * @see em_atomic_group_create(), em_queue_delete(), em_queue_create()
116 */
117em_queue_t
118em_queue_create_ag(const char *name, em_queue_prio_t prio,
119 em_atomic_group_t atomic_group, const em_queue_conf_t *conf);
120
121/**
122 * Create a new queue with a static queue handle belonging to an atomic group.
123 *
124 * Otherwise equivalent to em_queue_create_ag().
125 *
126 * Note that the number of static queues is provided by the user through
127 * 'queue.num_static' in em-odp.conf at runtime. A valid static queue handle
128 * can be derived as follows:
129 * @code
130 * em_status_t status;
131 * em_queue_t static_queue = em_queue_static_handle(x);
132 * status = em_queue_create_static_ag(NULL, EM_QUEUE_PRIO_NORMAL,
133 * atomic_group, static_queue, conf);
134 * @endcode
135 *
136 * The 'x' in above pseudocode must be in range 0 to 'queue.num_static' - 1.
137 *
138 * @param name Queue name (optional, NULL ok)
139 * @param prio Queue priority
140 * @param atomic_group Existing atomic group for this queue
141 * @param queue Requested queue handle from the static range
142 * @param conf Optional configuration data, NULL for defaults
143 *
144 * @return EM_OK if successful.
145 *
146 * @see em_queue_create_ag(), em_atomic_group_create(), em_queue_delete()
147 */
149em_queue_create_static_ag(const char *name, em_queue_prio_t prio,
150 em_atomic_group_t atomic_group, em_queue_t queue,
151 const em_queue_conf_t *conf);
152
153/**
154 * Get the name of an atomic group.
155 *
156 * A copy of the name string (up to 'maxlen' characters) is written to the user
157 * given buffer.
158 * The string is always null terminated, even if the given buffer length is less
159 * than the name length.
160 *
161 * If the atomic group has no name, the function returns 0 and writes an
162 * empty string.
163 *
164 * @param atomic_group Atomic group
165 * @param[out] name Destination buffer
166 * @param maxlen Maximum length (including the terminating '0')
167 *
168 * @return Number of characters written (excludes the terminating '0').
169 */
170size_t em_atomic_group_name(em_atomic_group_t atomic_group,
171 char *name, size_t maxlen);
172/* Backwards compatible naming ("get") */
173#define em_atomic_group_get_name em_atomic_group_name
174
175/**
176 * Find atomic group by name.
177 *
178 * Finds an atomic group by the given name (exact match). An empty string will
179 * not match anything. The search is case sensitive. If there are duplicate
180 * names, this will return the first match only.
181 *
182 * @param name the name to look for
183 *
184 * @return atomic group or EM_ATOMIC_GROUP_UNDEF if not found.
185 */
186em_atomic_group_t em_atomic_group_find(const char *name);
187
188/**
189 * Initialize atomic group iteration and return the first atomic group handle.
190 *
191 * Can be used to initialize the iteration to retrieve all created atomic groups
192 * for debugging or management purposes. Use em_atomic_group_next() after
193 * this call until it returns EM_ATOMIC_GROUP_UNDEF.
194 * A new call to em_atomic_group_first() resets the iteration, which is
195 * maintained per core (thread). The operation should be completed in one go
196 * before returning from the EO's event receive function (or start/stop).
197 *
198 * The number of atomic groups (output arg 'num') may not match the amount of
199 * atomic groups actually returned by iterating using em_atomic_group_next()
200 * if atomic groups are added or removed in parallel by another core. The order
201 * of the returned atomic group handles is undefined.
202 *
203 * @code
204 * unsigned int num;
205 * em_atomic_group_t ag = em_atomic_group_first(&num);
206 * while (ag != EM_ATOMIC_GROUP_UNDEF) {
207 * ag = em_atomic_group_next();
208 * }
209 * @endcode
210 *
211 * @param[out] num Pointer to an unsigned int to store the amount of
212 * atomic groups into
213 * @return The first atomic group handle or EM_ATOMIC_GROUP_UNDEF if none exist
214 *
215 * @see em_atomic_group_next()
216 */
217em_atomic_group_t em_atomic_group_first(unsigned int *num);
218
219/* Backwards compatible naming ("get") */
220#define em_atomic_group_get_first em_atomic_group_first
221
222/**
223 * Return the next atomic group handle.
224 *
225 * Continues the atomic group iteration started by em_atomic_group_first()
226 * and returns the next atomic group handle.
227 *
228 * @return The next atomic group handle or EM_ATOMIC_GROUP_UNDEF if the atomic
229 * group iteration is completed (i.e. no more atomic groups available).
230 *
231 * @see em_atomic_group_first()
232 */
233em_atomic_group_t em_atomic_group_next(void);
234
235/* Backwards compatible naming ("get") */
236#define em_atomic_group_get_next em_atomic_group_next
237
238/**
239 * Initialize iteration of an atomic group's queues and return the first
240 * queue handle.
241 *
242 * Can be used to initialize the iteration to retrieve all queues associated
243 * with the given atomic group for debugging or management purposes.
244 * Use em_atomic_group_queue_next() after this call until it returns
245 * EM_QUEUE_UNDEF.
246 * A new call to em_atomic_group_queue_first() resets the iteration, which
247 * is maintained per core (thread). The operation should be started and
248 * completed in one go before returning from the EO's event receive function (or
249 * start/stop).
250 *
251 * The number of queues in the atomic group (output arg 'num') may not match the
252 * amount of queues actually returned by iterating using
253 * em_atomic_group_queue_next() if queues are added or removed in parallel
254 * by another core. The order of the returned queue handles is undefined.
255 *
256 * Simplified example:
257 * @code
258 * unsigned int num;
259 * em_queue_t q = em_atomic_group_queue_first(&num, atomic_group);
260 * while (q != EM_QUEUE_UNDEF) {
261 * q = em_atomic_group_queue_next();
262 * }
263 * @endcode
264 *
265 * @param[out] num Pointer to unsigned int to store the amount of queues
266 * into.
267 * @param atomic_group Atomic group handle
268 *
269 * @return The first queue handle or EM_QUEUE_UNDEF if none exist or the
270 * atomic group is invalid.
271 *
272 * @see em_atomic_group_queue_next()
273 */
274em_queue_t em_atomic_group_queue_first(unsigned int *num,
275 em_atomic_group_t atomic_group);
276
277/* Backwards compatible naming ("get") */
278#define em_atomic_group_queue_get_first em_atomic_group_queue_first
279
280/**
281 * Return the atomic group's next queue handle.
282 *
283 * Continues the queue iteration started by em_atomic_group_queue_first()
284 * and returns the next queue handle in the atomic group.
285 *
286 * @return The next queue handle or EM_QUEUE_UNDEF if the queue iteration is
287 * completed (i.e. no more queues available for this atomic group).
288 *
289 * @see em_atomic_group_queue_first()
290 */
291em_queue_t em_atomic_group_queue_next(void);
292
293/* Backwards compatible naming ("get") */
294#define em_atomic_group_queue_get_next em_atomic_group_queue_next
295
296/**
297 * Convert an atomic group handle to an unsigned integer
298 *
299 * @param atomic_group atomic group handle to be converted
300 * @return uint64_t value that can be used to print/display the handle
301 *
302 * @note This routine is intended to be used for diagnostic purposes
303 * to enable applications to e.g. generate a printable value that represents
304 * an em_atomic_group_t handle.
305 */
306uint64_t em_atomic_group_to_u64(em_atomic_group_t atomic_group);
307
308/**
309 * @}
310 */
311#ifdef __cplusplus
312}
313#endif
314
315#pragma GCC visibility pop
316#endif /* EVENT_MACHINE_ATOMIC_GROUP_H_ */
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)
em_atomic_group_t em_atomic_group_find(const char *name)
em_queue_t em_atomic_group_queue_next(void)
uint64_t em_atomic_group_to_u64(em_atomic_group_t atomic_group)
em_queue_t em_atomic_group_queue_first(unsigned int *num, em_atomic_group_t atomic_group)
size_t em_atomic_group_name(em_atomic_group_t atomic_group, char *name, size_t maxlen)
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)
em_atomic_group_t em_atomic_group_next(void)
em_atomic_group_t em_atomic_group_first(unsigned int *num)
em_status_t em_atomic_group_delete(em_atomic_group_t atomic_group)
em_atomic_group_t em_atomic_group_create(const char *name, em_queue_group_t queue_group)
uint32_t em_status_t
uint32_t em_queue_prio_t