API Reference Manual
1.46.0
|
Event scheduler for work load balancing and prioritization.
Data Structures | |
struct | odp_schedule_param_t |
Scheduler parameters. More... | |
struct | odp_schedule_capability_t |
Scheduler capabilities. More... | |
struct | odp_schedule_config_t |
Schedule configuration. More... | |
struct | odp_schedule_group_info_t |
Schedule group information. More... | |
Macros | |
#define | ODP_SCHED_WAIT UINT64_MAX |
Wait infinitely. | |
#define | ODP_SCHED_NO_WAIT 0 |
Do not wait. | |
#define | ODP_SCHED_GROUP_NAME_LEN 32 |
Maximum schedule group name length, including the null character. | |
#define | ODP_SCHED_SYNC_PARALLEL 0 |
Parallel scheduled queues. More... | |
#define | ODP_SCHED_SYNC_ATOMIC 1 |
Atomic queue synchronization. More... | |
#define | ODP_SCHED_SYNC_ORDERED 2 |
Ordered queue synchronization. More... | |
#define | ODP_SCHED_GROUP_INVALID ((odp_schedule_group_t)-1) |
Invalid scheduler group. | |
#define | ODP_SCHED_GROUP_ALL 0 |
Group of all threads. More... | |
#define | ODP_SCHED_GROUP_WORKER 1 |
Group of all worker threads. More... | |
#define | ODP_SCHED_GROUP_CONTROL 2 |
Predefined scheduler group of all control threads. | |
Typedefs | |
typedef int | odp_schedule_sync_t |
Scheduler synchronization method. | |
typedef int | odp_schedule_group_t |
Scheduler thread group. | |
typedef int | odp_schedule_prio_t |
Scheduling priority level. More... | |
typedef struct odp_schedule_param_t | odp_schedule_param_t |
Scheduler parameters. | |
typedef struct odp_schedule_capability_t | odp_schedule_capability_t |
Scheduler capabilities. | |
typedef struct odp_schedule_config_t | odp_schedule_config_t |
Schedule configuration. | |
typedef struct odp_schedule_group_info_t | odp_schedule_group_info_t |
Schedule group information. | |
Functions | |
uint64_t | odp_schedule_wait_time (uint64_t ns) |
Schedule wait time. More... | |
odp_event_t | odp_schedule (odp_queue_t *from, uint64_t wait) |
Schedule an event. More... | |
int | odp_schedule_multi (odp_queue_t *from, uint64_t wait, odp_event_t events[], int num) |
Schedule multiple events. More... | |
int | odp_schedule_multi_wait (odp_queue_t *from, odp_event_t events[], int num) |
Schedule, wait for events. More... | |
int | odp_schedule_multi_no_wait (odp_queue_t *from, odp_event_t events[], int num) |
Schedule, do not wait for events. More... | |
void | odp_schedule_pause (void) |
Pause scheduling. More... | |
void | odp_schedule_resume (void) |
Resume scheduling. More... | |
void | odp_schedule_release_atomic (void) |
Release the current atomic context. More... | |
void | odp_schedule_release_ordered (void) |
Release the current ordered context. More... | |
void | odp_schedule_prefetch (int num) |
Prefetch events for next schedule call. More... | |
int | odp_schedule_max_prio (void) |
Maximum scheduling priority level. More... | |
int | odp_schedule_min_prio (void) |
Minimum scheduling priority level. More... | |
int | odp_schedule_default_prio (void) |
Default scheduling priority level. More... | |
int | odp_schedule_num_prio (void) |
Number of scheduling priorities. More... | |
void | odp_schedule_config_init (odp_schedule_config_t *config) |
Initialize schedule configuration options. More... | |
int | odp_schedule_config (const odp_schedule_config_t *config) |
Global schedule configuration. More... | |
int | odp_schedule_capability (odp_schedule_capability_t *capa) |
Query scheduler capabilities. More... | |
odp_schedule_group_t | odp_schedule_group_create (const char *name, const odp_thrmask_t *mask) |
Schedule group create. More... | |
int | odp_schedule_group_destroy (odp_schedule_group_t group) |
Schedule group destroy. More... | |
odp_schedule_group_t | odp_schedule_group_lookup (const char *name) |
Look up a schedule group by name. More... | |
int | odp_schedule_group_join (odp_schedule_group_t group, const odp_thrmask_t *mask) |
Join a schedule group. More... | |
int | odp_schedule_group_leave (odp_schedule_group_t group, const odp_thrmask_t *mask) |
Leave a schedule group. More... | |
int | odp_schedule_group_thrmask (odp_schedule_group_t group, odp_thrmask_t *thrmask) |
Get a schedule group's thrmask. More... | |
int | odp_schedule_group_info (odp_schedule_group_t group, odp_schedule_group_info_t *info) |
Retrieve information about a schedule group. More... | |
uint64_t | odp_schedule_group_to_u64 (odp_schedule_group_t group) |
Get printable value for schedule group handle. More... | |
void | odp_schedule_order_lock (uint32_t lock_index) |
Acquire ordered context lock. More... | |
void | odp_schedule_order_unlock (uint32_t lock_index) |
Release ordered context lock. More... | |
void | odp_schedule_order_unlock_lock (uint32_t unlock_index, uint32_t lock_index) |
Release existing ordered context lock and acquire a new lock. More... | |
void | odp_schedule_order_lock_start (uint32_t lock_index) |
Asynchronous ordered context lock Request an ordered context lock to be acquired. More... | |
void | odp_schedule_order_lock_wait (uint32_t lock_index) |
Asynchronous ordered context lock wait Wait for a previously started lock acquire operation to finish. More... | |
void | odp_schedule_order_wait (void) |
Wait until the currently held scheduling context is the first in order. More... | |
void | odp_schedule_print (void) |
Print debug info about scheduler. More... | |
#define ODP_SCHED_SYNC_PARALLEL 0 |
Parallel scheduled queues.
The scheduler performs priority scheduling, load balancing, prefetching, etc functions but does not provide additional event synchronization or ordering. It's free to schedule events from single parallel queue to multiple threads for concurrent processing. Application is responsible for queue context synchronization and event ordering (SW synchronization).
#define ODP_SCHED_SYNC_ATOMIC 1 |
Atomic queue synchronization.
Events from an atomic queue can be scheduled only to a single thread at a time. The thread is guaranteed to have exclusive (atomic) access to the associated queue context, which enables the user to avoid SW synchronization. Atomic queue also helps to maintain event ordering since only one thread at a time is able to process events from a queue.
The atomic queue synchronization context is dedicated to the thread until it requests another event from the scheduler, which implicitly releases the context. User may allow the scheduler to release the context earlier than that by calling odp_schedule_release_atomic(). However, this call is just a hint to the implementation and the context may be held until the next schedule call.
When scheduler is enabled as flow-aware, the event flow id value affects scheduling of the event and synchronization is maintained per flow within each queue.
#define ODP_SCHED_SYNC_ORDERED 2 |
Ordered queue synchronization.
Events from an ordered queue can be scheduled to multiple threads for concurrent processing but still maintain the original event order. This enables the user to achieve high single flow throughput by avoiding SW synchronization for ordering between threads.
When odp_schedule() returns an event, the calling thread is associated with an ordered scheduling synchronization context. The contexts arising from the same ordered queue have the same mutual ordering as the corresponding events had in the queue.
When odp_schedule_multi() returns more than one event from an ordered queue, the events returned were consecutive in the queue and the calling thread is associated with single ordered scheduling synchronization context that is ordered with respect to other contexts as if just the first event was returned.
When threads holding ordered scheduling synchronization contexts, which arise from the same ordered queue, enqueue events to destination queues, the order of events in each destination queue will be as follows:
The ordering rules above apply to all events, not just those that were scheduled from the ordered queue. For instance, newly allocated events and previously stored events are ordered in the destination queue based on the scheduling synchronization context. The ordering rules apply regarless of the type (scheduled or plain) or schedule type (atomic, ordered, or parallel) of the destination queue. If the order type of the destination queue is ODP_QUEUE_ORDER_IGNORE, then the order between events enqueued by different threads is not guaranteed.
An ordered scheduling synchronization context is implicitly released when the thread holding the context requests a new event from the scheduler. User may allow the scheduler to release the context earlier than that by calling odp_schedule_release_ordered(). However, this call is just a hint to the implementation and the context may be held until the next schedule call.
Enqueue calls by different threads may return in a different order than the final order of the enqueued events in the destination queue.
Unnecessary event re-ordering may be avoided for those destination queues that do not need to maintain the specified event order by setting 'order' queue parameter to ODP_QUEUE_ORDER_IGNORE.
When scheduler is enabled as flow-aware, the event flow id value affects scheduling of the event and synchronization is maintained and order is defined per flow within each queue.
#define ODP_SCHED_GROUP_ALL 0 |
Group of all threads.
All active worker and control threads belong to this group. The group is automatically updated when new threads enter or old threads exit ODP.
#define ODP_SCHED_GROUP_WORKER 1 |
Group of all worker threads.
All active worker threads belong to this group. The group is automatically updated when new worker threads enter or old threads exit ODP.
typedef int odp_schedule_prio_t |
Scheduling priority level.
Priority level is an integer value between odp_schedule_min_prio() and odp_schedule_max_prio(). Queues with a higher priority value are served with higher priority than queues with a lower priority value.
Definition at line 174 of file api/spec/schedule_types.h.
uint64_t odp_schedule_wait_time | ( | uint64_t | ns | ) |
Schedule wait time.
Converts nanoseconds to wait values for other schedule functions.
ns | Nanoseconds |
odp_event_t odp_schedule | ( | odp_queue_t * | from, |
uint64_t | wait | ||
) |
Schedule an event.
Run event scheduler to find the next highest priority event which is available for the calling thread. Only queues that have been created with ODP_QUEUE_TYPE_SCHED type are connected to the scheduler. Optionally, outputs the source queue of the event. If there's no event available, waits for an event according to the wait parameter setting. Returns ODP_EVENT_INVALID if reaches end of the wait period.
When returns an event, the thread holds the queue synchronization context (atomic or ordered) until the next schedule call (e.g. odp_schedule() or odp_schedule_multi()). The next call implicitly releases the current context and potentially returns with a new context. User can allow early context release (e.g., see odp_schedule_release_atomic() and odp_schedule_release_ordered()) for performance optimization.
When successful, this function acts as an acquire memory barrier between the sender and the receiver (the calling thread) of the event. The receiver sees correctly the memory stores done by the sender before it enqueued the event.
When the event was scheduled from an atomic queue, this function acts as an acquire memory barrier between the previous holder of the same atomic synchronization context and the calling thread. When the context is released, a release memory barrier is performed towards the next holder of the context. This ensures that memory stores done when holding an atomic context are correctly visible to other threads that will subsequently hold the same atomic context.
from | Output parameter for the source queue (where the event was dequeued from). Ignored if NULL. |
wait | Minimum time to wait for an event. Waits indefinitely if set to ODP_SCHED_WAIT. Does not wait if set to ODP_SCHED_NO_WAIT. Use odp_schedule_wait_time() to convert time to other wait values. |
ODP_EVENT_INVALID | on timeout and no events available |
int odp_schedule_multi | ( | odp_queue_t * | from, |
uint64_t | wait, | ||
odp_event_t | events[], | ||
int | num | ||
) |
Schedule multiple events.
Like odp_schedule(), but returns multiple events from a queue. The caller specifies the maximum number of events it is willing to accept. The scheduler is under no obligation to return more than a single event but will never return more than the number specified by the caller. The return code specifies the number of events returned and all of these events always originate from the same source queue and share the same scheduler synchronization context.
from | Output parameter for the source queue (where the event was dequeued from). Ignored if NULL. |
wait | Minimum time to wait for an event. Waits infinitely, if set to ODP_SCHED_WAIT. Does not wait, if set to ODP_SCHED_NO_WAIT. Use odp_schedule_wait_time() to convert time to other wait values. |
events | Event array for output |
num | Maximum number of events to output |
int odp_schedule_multi_wait | ( | odp_queue_t * | from, |
odp_event_t | events[], | ||
int | num | ||
) |
Schedule, wait for events.
Like odp_schedule_multi(), but waits infinitely for events.
[out] | from | Output parameter for the source queue (where the event was dequeued from). Ignored if NULL. |
[out] | events | Event array for output |
num | Maximum number of events to output |
int odp_schedule_multi_no_wait | ( | odp_queue_t * | from, |
odp_event_t | events[], | ||
int | num | ||
) |
Schedule, do not wait for events.
Like odp_schedule_multi(), but does not wait for events.
[out] | from | Output parameter for the source queue (where the event was dequeued from). Ignored if NULL. |
[out] | events | Event array for output |
num | Maximum number of events to output |
void odp_schedule_pause | ( | void | ) |
Pause scheduling.
Pause global scheduling for this thread. After this call, only ODP_SCHED_NO_WAIT schedule calls are allowed and these calls will return only locally pre-scheduled events (if any). User can exit the schedule loop only after the schedule function indicates that there's no more (pre-scheduled) events.
Example call pattern:
while (!stop) { odp_event_t ev = odp_schedule(NULL, ODP_SCHED_WAIT); // Process event }
while (1) { odp_event_t ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT); if (ev == ODP_EVENT_INVALID) break; odp_event_free(ev); }
void odp_schedule_resume | ( | void | ) |
Resume scheduling.
Resume global scheduling for this thread. After this call, all schedule calls will schedule normally (perform global scheduling).
void odp_schedule_release_atomic | ( | void | ) |
Release the current atomic context.
This call is valid only for source queues with atomic synchronization. It hints the scheduler that the user has completed critical section processing in the current atomic context. The scheduler is now allowed to schedule events from the same queue to another thread. However, the context may be still held until the next odp_schedule() or odp_schedule_multi() call - this call allows but does not force the scheduler to release the context early.
Early atomic context release may increase parallelism and thus system performance, but user needs to design carefully the split into critical vs. non-critical sections.
void odp_schedule_release_ordered | ( | void | ) |
Release the current ordered context.
This call is valid only for source queues with ordered synchronization. It hints the scheduler that the user has done all enqueues that need to maintain event order in the current ordered context. The scheduler is allowed to release the ordered context of this thread and avoid reordering any following enqueues. However, the context may be still held until the next odp_schedule() or odp_schedule_multi() call - this call allows but does not force the scheduler to release the context early.
Early ordered context release may increase parallelism and thus system performance, since scheduler may start reordering events sooner than the next schedule call.
void odp_schedule_prefetch | ( | int | num | ) |
Prefetch events for next schedule call.
Hint the scheduler that application is about to finish processing the current event(s) and will soon request more events. The scheduling context status is not affect. The call does not guarantee that the next schedule call will return any number of events. It may improve system performance, since the scheduler may prefetch the next (batch of) event(s) in parallel to application processing the current event(s).
num | Number of events to prefetch |
int odp_schedule_max_prio | ( | void | ) |
Maximum scheduling priority level.
This is the maximum value that can be set to 'prio' field in odp_schedule_param_t (e.g. odp_queue_create()). Queues with a higher priority value are served with higher priority than queues with a lower priority value.
int odp_schedule_min_prio | ( | void | ) |
Minimum scheduling priority level.
This is the minimum value that can be set to 'prio' field in odp_schedule_param_t (e.g. odp_queue_create()). Queues with a higher priority value are served with higher priority than queues with a lower priority value.
int odp_schedule_default_prio | ( | void | ) |
Default scheduling priority level.
This is the default value of 'prio' field in odp_schedule_param_t (e.g. odp_queue_param_init()). The default value should be suitable for an application that uses single priority level for all its queues (uses scheduler only for load balancing and synchronization). Typically, the default value is between minimum and maximum values, but with a few priority levels it may be close or equal to those.
int odp_schedule_num_prio | ( | void | ) |
Number of scheduling priorities.
The number of priority levels support by the scheduler. It equals to odp_schedule_max_prio() - odp_schedule_min_prio() + 1.
void odp_schedule_config_init | ( | odp_schedule_config_t * | config | ) |
Initialize schedule configuration options.
Initialize an odp_schedule_config_t to its default values.
[out] | config | Pointer to schedule configuration structure |
int odp_schedule_config | ( | const odp_schedule_config_t * | config | ) |
Global schedule configuration.
Initialize and configure scheduler with global configuration options to schedule events across different scheduled queues. This function must be called only once and before scheduler is used (any other scheduler function is called except odp_schedule_capability() and odp_schedule_config_init()) or any queues are created (by application itself or by other ODP modules). An application can pass NULL value to use default configuration. It will have the same result as filling the structure with odp_schedule_config_init() and then passing it to odp_schedule_config().
The initialization sequence should be:
config | Pointer to scheduler configuration structure or NULL for the default configuration |
0 | on success |
<0 | on failure |
int odp_schedule_capability | ( | odp_schedule_capability_t * | capa | ) |
Query scheduler capabilities.
Outputs schedule capabilities on success.
[out] | capa | Pointer to capability structure for output |
0 | on success |
<0 | on failure |
odp_schedule_group_t odp_schedule_group_create | ( | const char * | name, |
const odp_thrmask_t * | mask | ||
) |
Schedule group create.
Creates a schedule group with the thread mask. Only threads in the mask will receive events from a queue that belongs to the schedule group. Thread masks of various schedule groups may overlap. There are predefined groups, such as ODP_SCHED_GROUP_ALL and ODP_SCHED_GROUP_WORKER, which are present by default and are automatically updated. The use of group name is optional. Unique names are not required. However, odp_schedule_group_lookup() returns only a single matching group.
name | Name of the schedule group or NULL. Maximum string length is ODP_SCHED_GROUP_NAME_LEN, including the null character. |
mask | Thread mask |
ODP_SCHED_GROUP_INVALID | on failure |
int odp_schedule_group_destroy | ( | odp_schedule_group_t | group | ) |
Schedule group destroy.
Destroys a schedule group. All queues belonging to the schedule group must be destroyed before destroying the group. Other operations on this group must not be invoked in parallel.
group | Schedule group handle |
0 | on success |
<0 | on failure |
odp_schedule_group_t odp_schedule_group_lookup | ( | const char * | name | ) |
Look up a schedule group by name.
name | Name of schedule group |
ODP_SCHEDULE_GROUP_INVALID | No matching schedule group found |
int odp_schedule_group_join | ( | odp_schedule_group_t | group, |
const odp_thrmask_t * | mask | ||
) |
Join a schedule group.
Join a threadmask to an existing schedule group
group | Schedule group handle |
mask | Thread mask |
0 | on success |
<0 | on failure |
int odp_schedule_group_leave | ( | odp_schedule_group_t | group, |
const odp_thrmask_t * | mask | ||
) |
Leave a schedule group.
Remove a threadmask from an existing schedule group
group | Schedule group handle |
mask | Thread mask |
0 | on success |
<0 | on failure |
int odp_schedule_group_thrmask | ( | odp_schedule_group_t | group, |
odp_thrmask_t * | thrmask | ||
) |
Get a schedule group's thrmask.
group | Schedule group handle | |
[out] | thrmask | The current thrmask used for this schedule group |
0 | On success |
<0 | Invalid group specified |
int odp_schedule_group_info | ( | odp_schedule_group_t | group, |
odp_schedule_group_info_t * | info | ||
) |
Retrieve information about a schedule group.
Fills in schedule group information structure with current values. The call is not synchronized with calls modifying the schedule group. So, the application should ensure that it does not simultaneously modify and retrieve information about the same group with this call. The call is not intended for fast path use. The info structure is written only on success.
group | Schedule group handle | |
[out] | info | Pointer to schedule group info struct for output |
0 | On success |
<0 | On failure |
uint64_t odp_schedule_group_to_u64 | ( | odp_schedule_group_t | group | ) |
Get printable value for schedule group handle.
group | Handle to be converted for debugging |
void odp_schedule_order_lock | ( | uint32_t | lock_index | ) |
Acquire ordered context lock.
This call is valid only when holding an ordered synchronization context. Ordered locks are used to protect critical sections that are executed within an ordered context. Threads enter the critical section in the order determined by the context (source queue). Lock ordering is automatically skipped for threads that release the context instead of using the lock.
The number of ordered locks available is set by the lock_count parameter of the schedule parameters passed to odp_queue_create(), which must be less than or equal to queue capability 'max_ordered_locks'. If this routine is called outside of an ordered context or with a lock_index that exceeds the number of available ordered locks in this context results are undefined. The number of ordered locks associated with a given ordered queue may be queried by the odp_queue_lock_count() API.
Each ordered lock may be used only once per ordered context. If events are to be processed with multiple ordered critical sections, each should be protected by its own ordered lock. This promotes maximum parallelism by allowing order to maintained on a more granular basis. If an ordered lock is used multiple times in the same ordered context results are undefined. Only one ordered lock can be active in an ordered context at any given time. Results are undefined when multiple ordered locks are acquired in nested fashion within the same ordered context.
lock_index | Index of the ordered lock in the current context to be acquired. Must be in the range 0..odp_queue_lock_count()
|
void odp_schedule_order_unlock | ( | uint32_t | lock_index | ) |
Release ordered context lock.
This call is valid only when holding an ordered synchronization context. Release a previously locked ordered context lock.
lock_index | Index of the ordered lock in the current context to be released. Results are undefined if the caller does not hold this lock. Must be in the range 0..odp_queue_lock_count() - 1 |
void odp_schedule_order_unlock_lock | ( | uint32_t | unlock_index, |
uint32_t | lock_index | ||
) |
Release existing ordered context lock and acquire a new lock.
This call is valid only when holding an ordered synchronization context. Release a previously locked ordered context lock and acquire a new ordered context lock. The operation is equivalent to application calling first odp_schedule_order_unlock(unlock_index) and then odp_schedule_order_lock(lock_index). The same constraints apply with this call as with those two.
unlock_index | Index of the acquired ordered lock in the current context to be released. |
lock_index | Index of the ordered lock in the current context to be acquired. Must be in the range 0...odp_queue_lock_count() - 1. |
void odp_schedule_order_lock_start | ( | uint32_t | lock_index | ) |
Asynchronous ordered context lock Request an ordered context lock to be acquired.
Starts an ordered context lock acquire operation, but does not wait until the lock has been acquired. Application can use this call to potentially interleave some processing within waiting for this lock. Each start lock call must be paired with a wait call that blocks until the lock has been acquired. Locks cannot be acquired in nested fashion i.e each start call must follow a paring wait and unlock calls, before using another lock. The same constraints apply as with odp_schedule_order_lock()
lock_index | Index of the ordered lock in the current context to start acquire operation. Must be in the range 0..odp_queue_lock_count() - 1. |
void odp_schedule_order_lock_wait | ( | uint32_t | lock_index | ) |
Asynchronous ordered context lock wait Wait for a previously started lock acquire operation to finish.
Lock index must match with the previous start call. Ordered lock acquisition will be completed during this call.
lock_index | Index of the ordered lock in the current context to complete acquire operation. Must be in the range 0..odp_queue_lock_count() - 1. |
void odp_schedule_order_wait | ( | void | ) |
Wait until the currently held scheduling context is the first in order.
Wait until there are no other scheduling contexts that precede the scheduling context of the calling thread in the source queue order. The context remains the first in order until the thread releases it.
This function must not be called if the current thread is not holding an ordered scheduling context or if an ordered lock is being held.
This functions does nothing if ordered wait is not supported.
void odp_schedule_print | ( | void | ) |
Print debug info about scheduler.
Print implementation defined information about scheduler to the ODP log. The information is intended to be used for debugging.