EM-ODP  3.7.0
Event Machine on ODP
event_machine_atomic_group.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, 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 
56 #ifdef __cplusplus
57 extern "C" {
58 #endif
59 
61 
62 /**
63  * Create a new atomic group
64  *
65  * Some systems may have a limited number of atomic groups available or a
66  * limited number of queues per atomic group.
67  *
68  * The given name string is copied into an EM internal data structure. The
69  * maximum string length is EM_ATOMIC_GROUP_NAME_LEN. Duplicate names are
70  * allowed, but find will only match one of them.
71  *
72  * @param name Atomic group name (optional, NULL ok)
73  * @param queue_group Existing queue group to use for this atomic group
74  *
75  * @return Atomic group or EM_ATOMIC_GROUP_UNDEF on error.
76  */
77 em_atomic_group_t
78 em_atomic_group_create(const char *name, em_queue_group_t queue_group);
79 
80 /**
81  * Delete an atomic group.
82  *
83  * @attention An atomic group can only be deleted after all queues belonging
84  * to it have been removed from the EOs and deleted.
85  *
86  * @param atomic_group Atomic group to delete
87  *
88  * @return EM_OK if successful.
89  *
90  * @see em_atomic_group_create()
91  */
93 em_atomic_group_delete(em_atomic_group_t atomic_group);
94 
95 /**
96  * Create a new queue with a dynamic queue handle belonging to an atomic group.
97  *
98  * Queues created with this are always of type EM_QUEUE_TYPE_ATOMIC.
99  *
100  * The given name string is copied to EM internal data structure. The maximum
101  * string length is EM_QUEUE_NAME_LEN.
102  *
103  * The 'conf' argument is optional and can be used to pass extra attributes
104  * (e.g. require non-blocking behaviour, if supported) to the system specific
105  * implementation.
106  *
107  * @param name Queue name (optional, NULL ok)
108  * @param prio Queue priority
109  * @param atomic_group Existing atomic group for this queue
110  * @param conf Optional configuration data, NULL for defaults
111  *
112  * @return New queue handle or EM_QUEUE_UNDEF on an error.
113  *
114  * @see em_atomic_group_create(), em_queue_delete(), em_queue_create()
115  */
116 em_queue_t
117 em_queue_create_ag(const char *name, em_queue_prio_t prio,
118  em_atomic_group_t atomic_group, const em_queue_conf_t *conf);
119 
120 /**
121  * Create a new queue with a static queue handle belonging to an atomic group.
122  *
123  * Otherwise equivalent to em_queue_create_ag().
124  *
125  * Note, that the system may have a limited amount of static handles available,
126  * so prefer the use of dynamic queues, unless static handles are really needed.
127  * The range of static identifiers/handles is system dependent, but macros
128  * EM_QUEUE_STATIC_MIN and EM_QUEUE_STATIC_MAX can be used to abstract actual
129  * values, e.g. use EM_QUEUE_STATIC_MIN+x for the application.
130  *
131  * @param name Queue name (optional, NULL ok)
132  * @param prio Queue priority
133  * @param atomic_group Existing atomic group for this queue
134  * @param queue Requested queue handle from the static range
135  * @param conf Optional configuration data, NULL for defaults
136  *
137  * @return EM_OK if successful.
138  *
139  * @see em_queue_create_ag(), em_atomic_group_create(), em_queue_delete()
140  */
142 em_queue_create_static_ag(const char *name, em_queue_prio_t prio,
143  em_atomic_group_t atomic_group, em_queue_t queue,
144  const em_queue_conf_t *conf);
145 
146 /**
147  * Get the associated atomic group of the given queue.
148  *
149  * Returns the atomic group of the given queue.
150  *
151  * @param queue Queue for the query
152  *
153  * @return Queue specific atomic group or EM_ATOMIC_GROUP_UNDEF if
154  * the given queue is not valid or belong to an atomic group.
155  *
156  * @see em_atomic_group_create()
157  */
158 em_atomic_group_t
159 em_atomic_group_get(em_queue_t queue);
160 
161 /**
162  * Get the name of an atomic group.
163  *
164  * A copy of the name string (up to 'maxlen' characters) is written to the user
165  * given buffer.
166  * The string is always null terminated, even if the given buffer length is less
167  * than the name length.
168  *
169  * If the atomic group has no name, the function returns 0 and writes an
170  * empty string.
171  *
172  * @param atomic_group Atomic group
173  * @param[out] name Destination buffer
174  * @param maxlen Maximum length (including the terminating '0')
175  *
176  * @return Number of characters written (excludes the terminating '0').
177  */
178 size_t
179 em_atomic_group_get_name(em_atomic_group_t atomic_group,
180  char *name, size_t maxlen);
181 
182 /**
183  * Find atomic group by name.
184  *
185  * Finds an atomic group by the given name (exact match). An empty string will
186  * not match anything. The search is case sensitive. If there are duplicate
187  * names, this will return the first match only.
188  *
189  * @param name the name to look for
190  *
191  * @return atomic group or EM_ATOMIC_GROUP_UNDEF if not found.
192  */
193 em_atomic_group_t
194 em_atomic_group_find(const char *name);
195 
196 /**
197  * Initialize atomic group iteration and return the first atomic group handle.
198  *
199  * Can be used to initialize the iteration to retrieve all created atomic groups
200  * for debugging or management purposes. Use em_atomic_group_get_next() after
201  * this call until it returns EM_ATOMIC_GROUP_UNDEF.
202  * A new call to em_atomic_group_get_first() resets the iteration, which is
203  * maintained per core (thread). The operation should be completed in one go
204  * before returning from the EO's event receive function (or start/stop).
205  *
206  * The number of atomic groups (output arg 'num') may not match the amount of
207  * atomic groups actually returned by iterating using em_atomic_group_get_next()
208  * if atomic groups are added or removed in parallel by another core. The order
209  * of the returned atomic group handles is undefined.
210  *
211  * @code
212  * unsigned int num;
213  * em_atomic_group_t ag = em_atomic_group_get_first(&num);
214  * while (ag != EM_ATOMIC_GROUP_UNDEF) {
215  * ag = em_atomic_group_get_next();
216  * }
217  * @endcode
218  *
219  * @param[out] num Pointer to an unsigned int to store the amount of
220  * atomic groups into
221  * @return The first atomic group handle or EM_ATOMIC_GROUP_UNDEF if none exist
222  *
223  * @see em_atomic_group_get_next()
224  */
225 em_atomic_group_t
226 em_atomic_group_get_first(unsigned int *num);
227 
228 /**
229  * Return the next atomic group handle.
230  *
231  * Continues the atomic group iteration started by em_atomic_group_get_first()
232  * and returns the next atomic group handle.
233  *
234  * @return The next atomic group handle or EM_ATOMIC_GROUP_UNDEF if the atomic
235  * group iteration is completed (i.e. no more atomic groups available).
236  *
237  * @see em_atomic_group_get_first()
238  */
239 em_atomic_group_t
241 
242 /**
243  * Initialize iteration of an atomic group's queues and return the first
244  * queue handle.
245  *
246  * Can be used to initialize the iteration to retrieve all queues associated
247  * with the given atomic group for debugging or management purposes.
248  * Use em_atomic_group_queue_get_next() after this call until it returns
249  * EM_QUEUE_UNDEF.
250  * A new call to em_atomic_group_queue_get_first() resets the iteration, which
251  * is maintained per core (thread). The operation should be started and
252  * completed in one go before returning from the EO's event receive function (or
253  * start/stop).
254  *
255  * The number of queues in the atomic group (output arg 'num') may not match the
256  * amount of queues actually returned by iterating using
257  * em_atomic_group_queue_get_next() if queues are added or removed in parallel
258  * by another core. The order of the returned queue handles is undefined.
259  *
260  * Simplified example:
261  * @code
262  * unsigned int num;
263  * em_queue_t q = em_atomic_group_queue_get_first(&num, atomic_group);
264  * while (q != EM_QUEUE_UNDEF) {
265  * q = em_atomic_group_queue_get_next();
266  * }
267  * @endcode
268  *
269  * @param[out] num Pointer to unsigned int to store the amount of queues
270  * into.
271  * @param atomic_group Atomic group handle
272  *
273  * @return The first queue handle or EM_QUEUE_UNDEF if none exist or the
274  * atomic group is invalid.
275  *
276  * @see em_atomic_group_queue_get_next()
277  */
278 em_queue_t
279 em_atomic_group_queue_get_first(unsigned int *num,
280  em_atomic_group_t atomic_group);
281 
282 /**
283  * Return the atomic group's next queue handle.
284  *
285  * Continues the queue iteration started by em_atomic_group_queue_get_first()
286  * and returns the next queue handle in the atomic group.
287  *
288  * @return The next queue handle or EM_QUEUE_UNDEF if the queue iteration is
289  * completed (i.e. no more queues available for this atomic group).
290  *
291  * @see em_atomic_group_queue_get_first()
292  */
293 em_queue_t
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  */
306 uint64_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_atomic_group_get_next
em_atomic_group_t em_atomic_group_get_next(void)
Definition: event_machine_atomic_group.c:413
em_queue_conf_t
Definition: event_machine_types.h:212
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
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_atomic_group_to_u64
uint64_t em_atomic_group_to_u64(em_atomic_group_t atomic_group)
Definition: event_machine_atomic_group.c:517
em_atomic_group_queue_get_next
em_queue_t em_atomic_group_queue_get_next(void)
Definition: event_machine_atomic_group.c:492
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
em_status_t
uint32_t em_status_t
Definition: event_machine_types.h:321
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_delete
em_status_t em_atomic_group_delete(em_atomic_group_t atomic_group)
Definition: event_machine_atomic_group.c:181
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
event_machine_types.h
em_atomic_group_get
em_atomic_group_t em_atomic_group_get(em_queue_t queue)
Definition: event_machine_atomic_group.c:316