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