EM-ODP 4.4.0
Event Machine on ODP
Loading...
Searching...
No Matches
event_machine_queue_group.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2015-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_QUEUE_GROUP_H_
32#define EVENT_MACHINE_QUEUE_GROUP_H_
33
34#pragma GCC visibility push(default)
35
36/**
37 * @file
38 * @defgroup em_queue_group Queue group
39 * Operations on queue groups
40 *
41 * A queue group is basically a set of cores (threads) within an EM instance
42 * allowed to receive events from a queue belonging to that queue group.
43 *
44 * @{
45 */
46
50
51#ifdef __cplusplus
52extern "C" {
53#endif
54
55/**
56 * Create a new queue group to control queue to core mapping,
57 * asynchronous (non-blocking)
58 *
59 * Allocates a new queue group handle with a given core mask.
60 * Cores added to the queue group can be changed later with
61 * em_queue_group_modify().
62 *
63 * This operation may be asynchronous, i.e. the creation may complete well after
64 * this function has returned. Provide notification events, if the application
65 * needs to know about the actual completion. EM will send notifications when
66 * the operation has completed. Note that using a queue group before the
67 * creation has completed may result in undefined behaviour.
68 *
69 * The core mask is visible through em_queue_group_mask() only after the
70 * create operation has completed.
71 *
72 * Note, that the operation can also happen one core at a time, so an
73 * intermediate mask may be active momentarily.
74 *
75 * Only manipulate the core mask with the access macros defined in
76 * event_machine_core_mask.h as the implementation underneath may change.
77 *
78 * The given name is copied up to the maximum length of EM_QUEUE_GROUP_NAME_LEN.
79 * Duplicate names are allowed, but find will then only return the first match.
80 * The name "default" is reserved for EM_QUEUE_GROUP_DEFAULT.
81 *
82 * EM has a default group EM_QUEUE_GROUP_DEFAULT containing all cores running
83 * this EM instance. It's named "default".
84 *
85 * Some systems may have a low number of queue groups available.
86 *
87 * @attention Only call em_queue_create() after em_queue_group_create() has
88 * completed - use notifications to synchronize. Alternatively use
89 * em_queue_group_create_sync() to be able to create the queue
90 * directly after creating the queue group in the source code.
91 *
92 * @param name Queue group name (optional, NULL ok)
93 * @param mask Core mask for the queue group
94 * @param num_notif Number of entries in notif_tbl (use 0 for no notification)
95 * @param notif_tbl Array of notifications to send as the operation completes
96 *
97 * @return Queue group or EM_QUEUE_GROUP_UNDEF on error.
98 *
99 * @see em_queue_group_find(), em_queue_group_modify(), em_queue_group_delete(),
100 * em_queue_group_create_sync()
101 */
102em_queue_group_t
103em_queue_group_create(const char *name, const em_core_mask_t *mask,
104 int num_notif, const em_notif_t notif_tbl[]);
105
106/**
107 * Create a new queue group to control queue to core mapping,
108 * synchronous (blocking).
109 *
110 * As em_queue_group_create(), but will not return until the operation is
111 * complete.
112 *
113 * Note that the function is blocking and will not return until the operation
114 * has completed across all concerned EM cores.
115 * Sync-API calls can block the core for a long (indefinite) time, thus they
116 * should not be used to make runtime changes on real time EM cores - consider
117 * the async variants of the APIs in these cases instead.
118 * While one core is calling a sync-API function, the others must be running the
119 * EM dispatch loop to be able to receive and handle the sync-API request events
120 * sent internally.
121 * Use the sync-APIs mainly to simplify application start-up or teardown.
122 *
123 * @param name Queue group name (optional, NULL ok)
124 * @param mask Core mask for the queue group
125 *
126 * @return Queue group or EM_QUEUE_GROUP_UNDEF on error.
127 *
128 * @see em_queue_group_create() for an asynchronous version of the API
129 */
130em_queue_group_t
131em_queue_group_create_sync(const char *name, const em_core_mask_t *mask);
132
133/**
134 * Delete the queue group, asynchronous (non-blocking)
135 *
136 * Removes all cores from the queue group and free's the handle for reuse.
137 * All queues in the queue group must be deleted with em_queue_delete() before
138 * deleting the queue group.
139 *
140 * @param queue_group Queue group to delete
141 * @param num_notif Number of entries in notif_tbl (0 for no notification)
142 * @param notif_tbl Array of notifications to send as the operation completes
143 *
144 * @return EM_OK if successful.
145 *
146 * @see em_queue_group_create(), em_queue_group_modify(), em_queue_delete(),
147 * em_queue_group_delete_sync()
148 */
150em_queue_group_delete(em_queue_group_t queue_group,
151 int num_notif, const em_notif_t notif_tbl[]);
152
153/**
154 * Delete the queue group, synchronous (blocking).
155 *
156 * As em_queue_group_delete(), but will not return until the operation is
157 * complete.
158 *
159 * Note that the function is blocking and will not return until the operation
160 * has completed across all concerned EM cores.
161 * Sync-API calls can block the core for a long (indefinite) time, thus they
162 * should not be used to make runtime changes on real time EM cores - consider
163 * the async variants of the APIs in these cases instead.
164 * While one core is calling a sync-API function, the others must be running the
165 * EM dispatch loop to be able to receive and handle the sync-API request events
166 * sent internally.
167 * Use the sync-APIs mainly to simplify application start-up or teardown.
168 *
169 * @param queue_group Queue group to delete
170 *
171 * @return EM_OK if successful.
172 *
173 * @see em_queue_group_delete() for an asynchronous version of the API
174 */
176em_queue_group_delete_sync(em_queue_group_t queue_group);
177
178/**
179 * Modify the core mask of an existing queue group, asynchronous (non-blocking)
180 *
181 * The function compares the new core mask to the current mask and changes the
182 * core mapping for the given queue group accordingly.
183 *
184 * This operation may be asynchronous, i.e. the change may complete well after
185 * this function has returned. Provide notification events, if the application
186 * needs to know about the actual completion. EM will send notifications when
187 * the operation has completed.
188 *
189 * The new core mask is visible through em_queue_group_mask() only after
190 * the modify operation has completed.
191 *
192 * Note, that depending on the system, the change can also happen one core at
193 * a time, so an intermediate mask may be active momentarily.
194 *
195 * Only manipulate core mask with the access macros defined in
196 * event_machine_core_mask.h as the implementation underneath may change.
197 *
198 * @param queue_group Queue group to modify
199 * @param new_mask New core mask
200 * @param num_notif Number of entries in notif_tbl (0 for no notification)
201 * @param notif_tbl Array of notifications to send as the operation completes
202 *
203 * @return EM_OK if successful.
204 *
205 * @see em_queue_group_create(), em_queue_group_find(), em_queue_group_delete()
206 * em_queue_group_mask(), em_queue_group_modify_sync()
207 */
209em_queue_group_modify(em_queue_group_t queue_group,
210 const em_core_mask_t *new_mask,
211 int num_notif, const em_notif_t notif_tbl[]);
212
213/**
214 * Modify core mask of an existing queue group, synchronous (blocking).
215 *
216 * As em_queue_group_modify(), but will not return until the operation is
217 * complete.
218 *
219 * Note that the function is blocking and will not return until the operation
220 * has completed across all concerned EM cores.
221 * Sync-API calls can block the core for a long (indefinite) time, thus they
222 * should not be used to make runtime changes on real time EM cores - consider
223 * the async variants of the APIs in these cases instead.
224 * While one core is calling a sync-API function, the others must be running the
225 * EM dispatch loop to be able to receive and handle the sync-API request events
226 * sent internally.
227 * Use the sync-APIs mainly to simplify application start-up or teardown.
228 *
229 * @param queue_group Queue group to modify
230 * @param new_mask New core mask
231 *
232 * @return EM_OK if successful.
233 *
234 * @see em_queue_group_modify() for an asynchronous version of the API
235 */
237em_queue_group_modify_sync(em_queue_group_t queue_group,
238 const em_core_mask_t *new_mask);
239
240/**
241 * Finds a queue group by name.
242 *
243 * Finds a queue group by the given name (exact match). An empty string will not
244 * match anything. The search is case sensitive. If there are duplicate names,
245 * this will return the first match only.
246 *
247 * @param name Name of the queue qroup to find
248 *
249 * @return Queue group or EM_QUEUE_GROUP_UNDEF if not found
250 *
251 * @see em_queue_group_create()
252 */
253em_queue_group_t em_queue_group_find(const char *name);
254
255/**
256 * Get the current core mask for a queue group.
257 *
258 * This returns the situation at the moment of the inquiry. The result may not
259 * be up-to-date if another core is modifying the queue group at the same time.
260 * The application may need to synchronize group modifications.
261 *
262 * @param queue_group Queue group
263 * @param mask Core mask for the queue group
264 *
265 * @return EM_OK if successful.
266 *
267 * @see em_queue_group_create(), em_queue_group_modify()
268 */
269em_status_t em_queue_group_mask(em_queue_group_t queue_group,
270 em_core_mask_t *mask);
271
272/* Backwards compatible naming ("get") */
273#define em_queue_group_get_mask em_queue_group_mask
274
275/**
276 * Get the name of a queue group.
277 *
278 * A copy of the name string (up to 'maxlen' characters) is written to the user
279 * given buffer. The string is always null terminated, even if the given buffer
280 * length is less than the name length.
281 *
282 * The function returns '0' and writes an empty string if the queue group has
283 * no name.
284 *
285 * @param queue_group Queue group id
286 * @param[out] name Destination buffer
287 * @param maxlen Maximum length (including the terminating '\0')
288 *
289 * @return Number of characters written (excludes the terminating '\0').
290 */
291size_t em_queue_group_name(em_queue_group_t queue_group,
292 char *name, size_t maxlen);
293
294/* Backwards compatible naming ("get") */
295#define em_queue_group_get_name em_queue_group_name
296
297/**
298 * Initialize queue group iteration and return the first queue group handle.
299 *
300 * Can be used to initialize the iteration to retrieve all created queue groups
301 * for debugging or management purposes. Use em_queue_group_next() after
302 * this call until it returns EM_QUEUE_GROUP_UNDEF.
303 * A new call to em_queue_group_first() resets the iteration, which is
304 * maintained per core (thread). The operation should be completed in one go
305 * before returning from the EO's event receive function (or start/stop).
306 *
307 * The number of queue groups (output arg 'num') may not match the amount of
308 * queue groups actually returned by iterating using em_event_group_next()
309 * if queue groups are added or removed in parallel by another core. The order
310 * of the returned queue group handles is undefined.
311 *
312 * @code
313 * unsigned int num;
314 * em_queue_group_t qg = em_queue_group_first(&num);
315 * while (qg != EM_QUEUE_GROUP_UNDEF) {
316 * qg = em_queue_group_next();
317 * }
318 * @endcode
319 *
320 * @param[out] num Pointer to an unsigned int to store the amount of
321 * queue groups into
322 * @return The first queue group handle or EM_QUEUE_GROUP_UNDEF if none exist
323 *
324 * @see em_queue_group_next()
325 **/
326em_queue_group_t em_queue_group_first(unsigned int *num);
327
328/* Backwards compatible naming ("get") */
329#define em_queue_group_get_first em_queue_group_first
330
331/**
332 * Continues the queue group iteration started by em_queue_group_first() and
333 * returns the next queue group handle.
334 *
335 * @return The next queue group handle or EM_QUEUE_GROUP_UNDEF if the queue
336 * group iteration is completed (i.e. no more queue groups available).
337 *
338 * @see em_queue_group_first()
339 **/
340em_queue_group_t em_queue_group_next(void);
341
342/* Backwards compatible naming ("get") */
343#define em_queue_group_get_next em_queue_group_next
344
345/**
346 * Initialize iteration of a queue group's queues and return the first
347 * queue handle.
348 *
349 * Can be used to initialize the iteration to retrieve all queues associated
350 * with the given queue group for debugging or management purposes.
351 * Use em_queue_group_queue_next() after this call until it returns
352 * EM_QUEUE_UNDEF.
353 * A new call to em_queue_group_queue_first() resets the iteration, which is
354 * maintained per core (thread). The operation should be started and completed
355 * in one go before returning from the EO's event receive function (or
356 * start/stop).
357 *
358 * The number of queues in the queue group (output arg 'num') may not match the
359 * amount of queues actually returned by iterating using
360 * em_queue_group_queue_next() if queues are added or removed in parallel by
361 * another core. The order of the returned queue handles is undefined.
362 *
363 * Simplified example:
364 * @code
365 * unsigned int num;
366 * em_queue_t q = em_queue_group_queue_first(&num, queue_group);
367 * while (q != EM_QUEUE_UNDEF) {
368 * q = em_queue_group_queue_next();
369 * }
370 * @endcode
371 *
372 * @param[out] num Pointer to an unsigned int to store the amount of
373 * queue groups into.
374 * @param queue_group Queue group handle
375 *
376 * @return The first queue handle or EM_QUEUE_UNDEF if none exist or the
377 * queue group is invalid.
378 *
379 * @see em_queue_group_queue_next()
380 **/
381em_queue_t em_queue_group_queue_first(unsigned int *num,
382 em_queue_group_t queue_group);
383
384/* Backwards compatible naming ("get") */
385#define em_queue_group_queue_get_first em_queue_group_queue_first
386
387/**
388 * Return the queue group's next queue handle.
389 *
390 * Continues the queue iteration started by em_queue_group_queue_first() and
391 * returns the next queue handle in the queue group.
392 *
393 * @return The next queue handle or EM_QUEUE_UNDEF if the queue iteration is
394 * completed (i.e. no more queues available for this queue group).
395 *
396 * @see em_queue_group_queue_first()
397 **/
398em_queue_t em_queue_group_queue_next(void);
399
400/* Backwards compatible naming ("get") */
401#define em_queue_group_queue_get_next em_queue_group_queue_next
402
403/**
404 * Convert a queue_group handle to an unsigned integer
405 *
406 * @param queue_group queue_group handle to be converted
407 * @return uint64_t value that can be used to print/display the handle
408 *
409 * @note This routine is intended to be used for diagnostic purposes
410 * to enable applications to e.g. generate a printable value that represents
411 * an em_queue_group_t handle.
412 */
413uint64_t em_queue_group_to_u64(em_queue_group_t queue_group);
414
415/**
416 * @}
417 */
418#ifdef __cplusplus
419}
420#endif
421
422#pragma GCC visibility pop
423#endif /* EVENT_MACHINE_QUEUE_GROUP_H_ */
uint32_t em_status_t
em_queue_group_t em_queue_group_find(const char *name)
em_queue_group_t em_queue_group_first(unsigned int *num)
size_t em_queue_group_name(em_queue_group_t queue_group, char *name, size_t maxlen)
em_status_t em_queue_group_modify_sync(em_queue_group_t queue_group, const em_core_mask_t *new_mask)
em_queue_group_t em_queue_group_create(const char *name, const em_core_mask_t *mask, int num_notif, const em_notif_t notif_tbl[])
em_status_t em_queue_group_modify(em_queue_group_t queue_group, const em_core_mask_t *new_mask, int num_notif, const em_notif_t notif_tbl[])
em_queue_group_t em_queue_group_create_sync(const char *name, const em_core_mask_t *mask)
em_queue_group_t em_queue_group_next(void)
em_queue_t em_queue_group_queue_first(unsigned int *num, em_queue_group_t queue_group)
em_status_t em_queue_group_delete_sync(em_queue_group_t queue_group)
em_status_t em_queue_group_delete(em_queue_group_t queue_group, int num_notif, const em_notif_t notif_tbl[])
em_queue_t em_queue_group_queue_next(void)
uint64_t em_queue_group_to_u64(em_queue_group_t queue_group)
em_status_t em_queue_group_mask(em_queue_group_t queue_group, em_core_mask_t *mask)