EM-ODP  3.8.0-1
Event Machine on ODP
event_machine_dispatcher.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-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 #ifndef EVENT_MACHINE_DISPATCHER_H_
32 #define EVENT_MACHINE_DISPATCHER_H_
33 
34 #pragma GCC visibility push(default)
35 
36 /**
37  * @file
38  * @defgroup em_dispatcher Dispatcher
39  * Event Machine dispatcher related services.
40  * @{
41  *
42  * The EM dispatcher contains the main loop of processing on each EM-core and
43  * interfaces with the scheduler to obtain events for processing.
44  * Further, the EM dispatcher is responsible for passing the events received
45  * on a core, from the scheduler, to the correct EO-receive function along with
46  * information about which queue the events originated from, what their types
47  * are etc. Different flavours of the EM dispatch APIs exist along with
48  * configuration options.
49  *
50  * EM provides APIs to register, or unregister, dispatch callback hooks, i.e.
51  * user provided callback functions that will be run just before EM calls the
52  * EO-receive function or after returning from it. These callbacks are referred
53  * to as dispatch enter- and exit-callbacks respectively.
54  * The dispatch callbacks can be used to collect debug information, statistics
55  * or implement new functionality.
56  *
57  * The dispatch enter-callbacks are called before entering the EO-receive
58  * function on each EM-core separately. Events can be dropped by an enter-
59  * callback. Neither the EO-receive function nor any further enter-callbacks
60  * will be called if all events have been dropped by the callbacks already run.
61  * The callback itself needs to handle the events it drops, e.g. free them.
62  *
63  * The dispatch exit-callbacks are called after the EO-receive function returns
64  * and have no arguments except for the EO handle. Note that all exit-callbacks
65  * are always called (even if the enter-callbacks dropped the events causing the
66  * rest of the enter-callbacks and the EO-receive function to be skipped).
67  *
68  * Multiple callbacks can be registered. The calling order of multiple
69  * registered callbacks is the order of registration. If the same function is
70  * registered twice then it will be called twice. The max amount of simultaneous
71  * callbacks is set by the define 'EM_CALLBACKS_MAX'.
72  *
73  * EM does not know of any connection or relationship between registered
74  * dispatch enter- and/or exit-callbacks. All dispatch callbacks are treated as
75  * independent entries. Functionality that e.g. depends on both an enter- and an
76  * exit-callback being run must take into acconut that the previous
77  * enter-callbacks might have dropped all events, thus skipping the following
78  * enter-callbacks - but still running all exit-callbacks.
79  */
80 
81 #ifdef __cplusplus
82 extern "C" {
83 #endif
84 
87 
88 /**
89  * @brief EM dispatch duration selection flags
90  *
91  * Combining (bitwise OR) several DURATION flags will instruct the EM dispatcher
92  * to dispatch until the first 'duration' condition is met, whichever happens
93  * first.
94  */
95 typedef enum {
96  /** Select: dispatch forever, never return */
98  /** Select: dispatch until em_dispatch_opt_t::duration.rounds reached */
100  /** Select: dispatch until em_dispatch_opt_t::duration.ns reached */
102  /** Select: dispatch until em_dispatch_opt_t::duration.events reached */
104 
105  /** Select: dispatch until em_dispatch_opt_t::duration.no_events.rounds reached */
107  /** Select: dispatch until em_dispatch_opt_t::duration.no_events.ns reached */
109 
110  /* Keep last, for error checking */
111  EM_DISPATCH_DURATION_LAST
113 
114 /**
115  * Dispatch duration.
116  *
117  * Select which dispatch duration, or combination, is to be used with the
118  * em_dispatch_duration() function.
119  * Bitwise OR .select-flags for a combination.
120  * Dispatch will end when one of the selected 'duration' options is
121  * reached, whichever is hit first.
122  */
123 typedef struct {
124  /**
125  * Select which 'duration'-fields that should be taken into account
126  * when evaluating the em_dispatch_duration() run time.
127  *
128  * Only the duration fields that correspond to set .select-flags
129  * will be used.
130  */
132 
133  /*
134  * Duration fields / values below considered according to .select-flags:
135  */
136 
137  /**
138  * Dispatch for the given number of rounds, if used must be > 0.
139  * Only considered if .select contains EM_DISPATCH_DURATION_ROUNDS.
140  */
141  uint64_t rounds;
142 
143  /**
144  * Dispatch (at least) for the given time in nanoseconds,
145  * if used must be > 0.
146  * Only considered if .select contains EM_DISPATCH_DURATION_NS.
147  *
148  * Using a large value for the option 'wait_ns' relative to .ns
149  * might delay the return from dispatch.
150  *
151  * The runtime of the EO-receive function for the last batch of events
152  * is not covered by .ns.
153  * EM will request new events to dispatch while the
154  * elapsed dispatch time is < .ns.
155  */
156  uint64_t ns;
157 
158  /**
159  * Dispatch until (at least) the given number of events have been
160  * handled, if used must be > 0.
161  * Only considered if .select contains EM_DISPATCH_DURATION_EVENTS.
162  *
163  * Note that the option 'burst_size' affects the number of events
164  * dispatched. EM will request new events to dispatch while the number
165  * of dispatched events is < .events and then handle the whole burst.
166  *
167  * The option 'sched_pause=true' might also increase the number of
168  * events dispatched since the EM dispatcher needs to fetch and handle
169  * any leftover events held locally by the scheduler before returning.
170  */
171  uint64_t events;
172 
173  struct {
174  /**
175  * Dispatch until no events have been received for the
176  * given number of rounds, if used must be > 0.
177  * Only considered if .select contains
178  * EM_DISPATCH_DURATION_NO_EVENTS_ROUNDS.
179  */
180  uint64_t rounds;
181 
182  /**
183  * Dispatch until no events have been received for the
184  * given time in nanoseconds, if used must be > 0.
185  * Only considered if .select contains
186  * EM_DISPATCH_DURATION_NO_EVENTS_NS.
187  */
188  uint64_t ns;
189  } no_events;
191 
192 /**
193  * @brief EM dispatch options
194  *
195  * The options must be initialized once with em_dispatch_opt_init() before
196  * using them with other em_dispatch_...() calls for the first time. Further
197  * calls to em_dispatch_...() with the same options structure do not need
198  * initialization and the user is allowed to modify the options between calls
199  * to change the dispatch behaviour.
200  *
201  * @see em_dispatch_opt_init(), em_dispatch_duration() etc.
202  */
203 typedef struct {
204  /**
205  * Scheduler wait-for-events timeout in nanoseconds, might save power.
206  * The scheduler will wait for events, if no immediately available, for
207  * 'wait_ns' nanoseconds per scheduling / dispatch round.
208  *
209  * Note that using a large 'wait_ns' value relative to a
210  * dispatch duration in 'ns' might delay the return from dispatch.
211  *
212  * 0: do not wait for events (default)
213  */
214  uint64_t wait_ns;
215 
216  /**
217  * Scheduler burst size.
218  * The max number of events the dispatcher will request in one burst
219  * from the scheduler.
220  *
221  * default: EM_SCHED_MULTI_MAX_BURST
222  */
223  uint16_t burst_size;
224 
225  /**
226  * Override the possibly configured dispatcher input-polling callback
227  * (set via em_conf_t::input.input_poll_fn).
228  *
229  * false: Do not skip the input-poll callback if configured (default).
230  * true: Skip the input-poll callback in the dispatcher.
231  */
232  bool skip_input_poll; /* override em_conf_t configuration */
233 
234  /**
235  * Override the possibly configured dispatcher output-drain callback
236  * (set via em_conf_t::output.output_drain_fn).
237  *
238  * false: Do not skip the output-drain callback if configured (default).
239  * true: Skip the output-drain callback in the dispatcher.
240  */
241  bool skip_output_drain; /* override em_conf_t configuration */
242 
243  /**
244  * Pause the scheduler on the calling core when exiting the EM dispatch
245  * function. If enabled, will also resume the scheduling when entering
246  * dispatch. Pausing also implicitly causes the dispatcher to fetch and
247  * handle any leftover events held locally by the scheduler before
248  * returning.
249  *
250  * false: Do not pause and resume the scheduler when entering and
251  * exiting dispatch (default).
252  * true: Pause scheduling when exiting dispatch and resume scheduling
253  * when entering. EM will further empty and dispatch any remaining
254  * events locally stashed in the scheduler before returning
255  * causing some extra dispatch 'rounds' to be run.
256  */
258 
259  /**
260  * Internal check - don't touch!
261  *
262  * EM will verify that em_dispatch_opt_init(opt) has been called
263  * before use with dispatch functions.
264  */
267 
268 /**
269  * @brief Dispatch results
270  *
271  * Output struct for returning the results of the em_dispatch_...() functions
272  * in. Usage of 'em_dispatch_results_t *results' with dispatch functions is
273  * optional and 'NULL' can be used if not interested in the results.
274  */
275 typedef struct {
276  /**
277  * The number of dispatch rounds that were run.
278  */
279  uint64_t rounds;
280 
281  /**
282  * The time in nanoseconds that dispatch was run.
283  * Only filled if requesting EM to dispatch for a certain amount of
284  * time, i.e. if EM_DISPATCH_DURATION_NS or
285  * EM_DISPATCH_DURATION_NO_EVENTS_NS duration selection flags were set
286  * in em_dispatch_duration_t::select when using em_dispatch_duration().
287  * Also set when used with em_dispatch_ns().
288  */
289  uint64_t ns;
290 
291  /**
292  * The number of events that were dispatched.
293  */
294  uint64_t events;
296 
297 /**
298  * @brief Initialize the EM dispatch options.
299  *
300  * The options passed to em_dispatch_...() need to be initialized once before
301  * first use. Further calls to em_dispatch_...() with the same options structure
302  * do not need initialization and the user is allowed to modify the options
303  * between calls to change dispatch behaviour.
304  *
305  * This function may be called before em_init() or em_init_core() since it only
306  * sets the default values for the 'em_dispatch_opt_t *opt' argument.
307  *
308  * @param opt
309  */
311 
312 /**
313  * @brief Run the EM dispatcher for a certain duration with options.
314  *
315  * Called by an EM-core to dispatch (with options) events for EM processing.
316  * The EM dispatcher internally queries the scheduler for events for the
317  * calling EM-core and then dispatches them for processing, i.e. passes the
318  * events to the application EO's receive-function based on the queue the events
319  * were received / dequeued from.
320  *
321  * Combining (bitwise OR) several DURATION selection flags
322  * (see em_dispatch_duration_select_t) will dispatch until the first
323  * duration-condition is met, whichever happens first.
324  *
325  * Example usage:
326  * @code
327  * em_dispatch_duration_t duration;
328  * em_dispatch_opt_t opt;
329  * em_dispatch_results_t results;
330  * em_status_t status;
331  *
332  * em_dispatch_opt_init(&opt); // Mandatory once before first use!
333  * opt.wait_ns = 10000; // Wait max 10 us for events from scheduler
334  * opt.sched_pause = false; // Don't pause scheduling on return
335  *
336  * // Dispatch for 1000 rounds, 200 us or until 300 events have been
337  * // handled. Return when the first of these conditions is met.
338  * duration.select = EM_DISPATCH_DURATION_ROUNDS |
339  * EM_DISPATCH_DURATION_NS |
340  * EM_DISPATCH_DURATION_EVENTS;
341  * duration.rounds = 1000;
342  * duration.ns = 200000; // 200 us
343  * duration.events = 300;
344  * ...
345  * do {
346  * // Dispatch until '.rounds' or '.ns' or '.events' reached
347  * status = em_dispatch_duration(&duration, &opt, &results);
348  * ...
349  * // Update 'duration' and 'opt' based on 'results'
350  * // and/or runtime conditions
351  * } while (do_dispatch(&results, ...));
352  *
353  * // Prepare to leave EM dispatching
354  * duration.select = EM_DISPATCH_DURATION_NO_EVENTS_NS;
355  * duration.no_events.ns = 100000;
356  * opt.wait_ns = 0; // No waiting for events
357  * opt.skip_input_poll = true; // No callbacks
358  * opt.skip_output_drain = true; // -"-
359  * opt.sched_pause = true; // Pause scheduling on this EM-core
360  *
361  * status = em_dispatch_duration(&duration, &opt, &results);
362  * // Leave EM dispatching for a while
363  * @endcode
364  *
365  * @param duration Dispatch duration.
366  * @param opt Dispatch options (optional, can be NULL).
367  * If used, must have been initialized with
368  * em_dispatch_opt_init(). One initialization is enough,
369  * later calls to em_dispatch_...(...opt) can reuse (the
370  * possibly modified) 'opt'.
371  * Using NULL is the same as passing 'opt' initialized
372  * with em_dispatch_opt_init(&opt) without further changes.
373  * @param[out] results Dispatch results (optional, can be NULL).
374  * Filled for successful dispatch scenarios, i.e. when the
375  * return value is EM_OK.
376  *
377  * @return Error status code
378  * @retval EM_OK when dispatch was successful, 'result' is filled (if provided)
379  * @retval other than EM_OK on error, 'result' is untouched
380  */
382  const em_dispatch_opt_t *opt,
383  em_dispatch_results_t *results /*out*/);
384 /**
385  * @brief Run the EM dispatcher for a given amount of time (in nanoseconds).
386  *
387  * Similar to em_dispatch_duration(), but with a simplified dispatch duration:
388  * here only the number of nanoseconds to dispatch is provided.
389  *
390  * Using a large value for 'opt.wait_ns' relative to 'ns' might delay the
391  * return from dispatch.
392  *
393  * The runtime of the EO-receive function for the last batch of events
394  * is not covered by 'ns'.
395  * EM will request new events to dispatch while the elapsed time is < 'ns'.
396  *
397  * @see em_dispatch_duration() for documentation and usage.
398  *
399  * @param ns Dispatch duration in nanoseconds.
400  * Note that 'ns=0' is not allowed!
401  * @param opt Dispatch options (optional, can be NULL).
402  * If used, must have been initialized with
403  * em_dispatch_opt_init(). One initialization is enough,
404  * later calls to em_dispatch_...(...opt) can reuse (the
405  * possibly modified) 'opt'.
406  * Using NULL is the same as passing 'opt' initialized
407  * with em_dispatch_opt_init(&opt) without further changes.
408  * @param[out] results Dispatch results (optional, can be NULL).
409  * Filled for successful dispatch scenarios, i.e. when the
410  * return value is EM_OK.
411  *
412  * @return Error status code
413  * @retval EM_OK when dispatch was successful, 'result' is filled (if provided)
414  * @retval other than EM_OK on error, 'result' is untouched
415  */
416 em_status_t em_dispatch_ns(uint64_t ns,
417  const em_dispatch_opt_t *opt,
418  em_dispatch_results_t *results /*out*/);
419 
420 /**
421  * @brief Run the EM dispatcher until a given number of events have been
422  * dispatched.
423  *
424  * Similar to em_dispatch_duration(), but with a simplified dispatch duration:
425  * here only the number of events to dispatch is provided.
426  *
427  * Note that 'opt.burst_size' affects the number of events dispatched.
428  * EM will request new events to dispatch while the number of dispatched
429  * events is < .events and then handle the whole burst.
430  *
431  * The option 'opt.sched_pause=true' might also increase the number of
432  * events dispatched since the EM dispatcher needs to fetch and handle
433  * any leftover events held locally by the scheduler before returning.
434  *
435  * @see em_dispatch_duration() for documentation and usage.
436  *
437  * @param events Dispatch duration events. Dispatch until the given
438  * number of events have been dispatched.
439  * Note that 'events=0' is not allowed!
440  * @param opt Dispatch options (optional, can be NULL).
441  * If used, must have been initialized with
442  * em_dispatch_opt_init(). One initialization is enough,
443  * later calls to em_dispatch_...(...opt) can reuse (the
444  * possibly modified) 'opt'.
445  * Using NULL is the same as passing 'opt' initialized
446  * with em_dispatch_opt_init(&opt) without further changes.
447  * @param[out] results Dispatch results (optional, can be NULL).
448  * Filled for successful dispatch scenarios, i.e. when the
449  * return value is EM_OK.
450  *
451  * @return Error status code
452  * @retval EM_OK when dispatch was successful, 'result' is filled (if provided)
453  * @retval other than EM_OK on error, 'result' is untouched
454  */
455 em_status_t em_dispatch_events(uint64_t events,
456  const em_dispatch_opt_t *opt,
457  em_dispatch_results_t *results /*out*/);
458 
459 /**
460  * @brief Run the EM dispatcher for a given number of dispatch-rounds.
461  *
462  * Similar to em_dispatch_duration(), but with a simplified dispatch duration:
463  * here only the number of rounds to dispatch is provided.
464  *
465  * @see em_dispatch_duration() for documentation and usage.
466  *
467  * @param rounds Dispatch duration rounds. Dispatch for the given number
468  * of rounds.
469  * Note that 'rounds=0' is not allowed!
470  * @param opt Dispatch options (optional, can be NULL).
471  * If used, must have been initialized with
472  * em_dispatch_opt_init(). One initialization is enough,
473  * later calls to em_dispatch_...(...opt) can reuse (the
474  * possibly modified) 'opt'.
475  * Using NULL is the same as passing 'opt' initialized
476  * with em_dispatch_opt_init(&opt) without further changes.
477  * @param[out] results Dispatch results (optional, can be NULL).
478  * Filled for successful dispatch scenarios, i.e. when the
479  * return value is EM_OK.
480  *
481  * @return Error status code
482  * @retval EM_OK when dispatch was successful, 'result' is filled (if provided)
483  * @retval other than EM_OK on error, 'result' is untouched
484  */
485 em_status_t em_dispatch_rounds(uint64_t rounds,
486  const em_dispatch_opt_t *opt,
487  em_dispatch_results_t *results /*out*/);
488 
489 /**
490  * EM event dispatch
491  *
492  * Called by an EM-core to dispatch events for EM processing.
493  * The EM dispatcher internally queries the scheduler for events for the
494  * calling EM-core and then dispatches them for processing, i.e. passes the
495  * events to the application EO's receive-function based on the queue the events
496  * were received / dequeued from.
497  *
498  * See the EM config file for options controlling the global behaviour of
499  * em_dispatch().
500  *
501  * @param rounds Dispatch rounds before returning,
502  * 0 means 'never return from dispatch'
503  *
504  * @return The number of events dispatched on this core.
505  * Only makes sense if 'rounds > 0'
506  *
507  * @see em_dispatch_duration() for a function that enables dispatching
508  * with more options.
509  */
510 uint64_t em_dispatch(uint64_t rounds);
511 
512 /**
513  * Dispatch enter-callback.
514  *
515  * Common dispatch callback run before EO-receive functions of both the
516  * em_receive_func_t and em_receive_multi_func_t types (i.e. for EOs created
517  * with either em_eo_create() or em_eo_create_multircv()).
518  *
519  * Enter-callbacks are run just before entering EO-receive functions, they can
520  * be useful for debugging, collecting statistics, manipulating events before
521  * they reach the EO or implementing new services needing synchronization
522  * between cores.
523  * Some of the arguments common for both types of EO receive functions are
524  * passed as pointers to the enter-callback so that the callback can optionally
525  * modify them. If modified, the new values will go to the next callback and
526  * eventually to the EO-receive function.
527  *
528  * Events can be dropped by changing the event-entries in the events[num]-array
529  * to EM_EVENT_UNDEF. Neither EO-receive nor any further enter-callbacks will
530  * be called if all events have been dropped by the callbacks already run, i.e.
531  * no callback will be called with 'num=0'.
532  * The callback itself needs to handle the events it drops, e.g. free them.
533  * Note: EM will remove entries of EM_EVENT_UNDEF from the events[]-array before
534  * calling the next enter-callback (if several registered) or the
535  * receive function and adjust 'num' accordingly for the call.
536  *
537  * Functionality that e.g. depends on both an enter- and an exit-callback being
538  * run must take into acconut that the previous enter-callbacks might have
539  * dropped all events, thus skipping the following enter-callbacks - but still
540  * running all exit-callbacks.
541  *
542  * The EO handle can be used to separate callback functionality per EO and the
543  * core id can be obtained for core specific functionality.
544  *
545  * Callback functions can be called concurrently from different cores.
546  *
547  * @see em_dispatch_register_enter_cb()
548  */
549 typedef void (*em_dispatch_enter_func_t)(em_eo_t eo, void **eo_ctx,
550  em_event_t events[/*in/out*/], int num,
551  em_queue_t *queue, void **q_ctx);
552 
553 /**
554  * Dispatcher exit-callback.
555  *
556  * The exit-callbacks are run after EO-receive returns.
557  * Some arguments given to EO-receive might not be valid afterwards, thus
558  * the only argument given to the exit callback is the EO handle.
559  *
560  * Callback functions can be called concurrently from different cores.
561  *
562  * Functionality that e.g. depends on both an enter- and an exit-callback being
563  * run must take into acconut that the previous enter-callbacks might have
564  * dropped all events, thus skipping the following enter-callbacks - but still
565  * running all exit-callbacks.
566  *
567  * @see em_dispatch_register_exit_cb()
568  */
569 typedef void (*em_dispatch_exit_func_t)(em_eo_t eo);
570 
571 /**
572  * Register a dispatch enter-callback
573  *
574  * Register a global function to be called by the dispatcher just before calling
575  * an EO-receive function. This can be useful for debugging, collecting
576  * statistics, manipulating events before they reach the EO or implementing new
577  * services needing synchronization between cores.
578  *
579  * The function registered should be kept short since it will be run each time
580  * just before calling EO-receive. All registered callbacks will further
581  * increase the processing time.
582  *
583  * Multiple callbacks can be registered.
584  * The order of calling multiple registered functions is the order of
585  * registration. If same function is registered twice it will be called twice.
586  * The maximum number of simultaneous callbacks is system specific
587  * (EM_CALLBACKS_MAX).
588  *
589  * @param func Dispatch enter-callback function
590  *
591  * @return EM_OK if callback registration succeeded
592  *
593  * @see em_dispatch_enter_func_t for further documentation
594  */
596 
597 /**
598  * Unregister a dispatch enter-callback
599  *
600  * This can be used to unregister a previously registered enter-callback.
601  *
602  * The given function is searched for and, if found, removed from the call list.
603  * If the same function has been registered multiple times, only one reference
604  * is removed per unregister call.
605  * Note that when this function returns, no new calls are made to the removed
606  * callback function, but it is still possible that another core could be
607  * executing the function, so care must be taken before removing anything it may
608  * still use.
609  *
610  * @param func Dispatch enter-callback function
611  *
612  * @return EM_OK if the given function was found and removed.
613  */
615 
616 /**
617  * Register a dispatch exit-callback
618  *
619  * Register a global function to be called by the dispatcher just after return
620  * from an EO-receive function.
621  *
622  * The function registered should be kept short since it will be run each time
623  * just after EO-receive returns. All registered callbacks will further increase
624  * the processing time.
625  *
626  * Multiple callbacks can be registered.
627  * The order of calling multiple registered functions is the order of
628  * registration. If same function is registered twice it will be called twice.
629  * The maximum number of simultaneous callbacks is system specific
630  * (EM_CALLBACKS_MAX).
631  *
632  * @param func Dispatch exit-callback function
633  *
634  * @return EM_OK if callback registration succeeded
635  *
636  * @see em_dispatch_exit_func_t for further documentation
637  */
639 
640 /**
641  * Unregister a dispatch exit-callback
642  *
643  * This can be used to unregister a previously registered exit-callback.
644  *
645  * The given function is searched for and, if found, removed from the call list.
646  * If the same function has been registered multiple times, only one reference
647  * is removed per unregister call.
648  * Note that when this function returns, no new calls are made to the removed
649  * callback function, but it is still possible that another core could be
650  * executing the function, so care must be taken before removing anything it may
651  * still use.
652  *
653  * @param func Dispatch exit-callback function
654  *
655  * @return EM_OK if the given function was found and removed.
656  *
657  * @see em_dispatch_exit_func_t
658  */
660 
661 /**
662  * @}
663  */
664 #ifdef __cplusplus
665 }
666 #endif
667 
668 #pragma GCC visibility pop
669 #endif /* EVENT_MACHINE_DISPATCHER_H_ */
uint32_t em_status_t
em_status_t em_dispatch_events(uint64_t events, const em_dispatch_opt_t *opt, em_dispatch_results_t *results)
Run the EM dispatcher until a given number of events have been dispatched.
em_status_t em_dispatch_unregister_exit_cb(em_dispatch_exit_func_t func)
em_status_t em_dispatch_register_enter_cb(em_dispatch_enter_func_t func)
uint64_t em_dispatch(uint64_t rounds)
void em_dispatch_opt_init(em_dispatch_opt_t *opt)
Initialize the EM dispatch options.
em_status_t em_dispatch_register_exit_cb(em_dispatch_exit_func_t func)
em_status_t em_dispatch_ns(uint64_t ns, const em_dispatch_opt_t *opt, em_dispatch_results_t *results)
Run the EM dispatcher for a given amount of time (in nanoseconds).
em_status_t em_dispatch_rounds(uint64_t rounds, const em_dispatch_opt_t *opt, em_dispatch_results_t *results)
Run the EM dispatcher for a given number of dispatch-rounds.
em_status_t em_dispatch_unregister_enter_cb(em_dispatch_enter_func_t func)
em_status_t em_dispatch_duration(const em_dispatch_duration_t *duration, const em_dispatch_opt_t *opt, em_dispatch_results_t *results)
Run the EM dispatcher for a certain duration with options.
void(* em_dispatch_enter_func_t)(em_eo_t eo, void **eo_ctx, em_event_t events[], int num, em_queue_t *queue, void **q_ctx)
void(* em_dispatch_exit_func_t)(em_eo_t eo)
em_dispatch_duration_select_t
EM dispatch duration selection flags.
@ EM_DISPATCH_DURATION_ROUNDS
@ EM_DISPATCH_DURATION_NO_EVENTS_NS
@ EM_DISPATCH_DURATION_EVENTS
@ EM_DISPATCH_DURATION_NS
@ EM_DISPATCH_DURATION_FOREVER
@ EM_DISPATCH_DURATION_NO_EVENTS_ROUNDS
em_dispatch_duration_select_t select
EM dispatch options.