Both user space and kernel
threads are based on EVL core
threads, which descriptor is struct evl_thread
in the
implementation. An EVL thread running in user space is fully described
by the struct evl_thread
type. On the other hand, an EVL kernel
thread extends a struct evl_thread
core thread, i.e.:
struct evl_kthread {
struct evl_thread thread;
...
};
This document describes the public API which is usable with any EVL
thread, running in user or kernel space. Anywhere struct evl_thread *
is accepted in the API, given a struct evl_kthread kthread
descriptor, you may pass &kthread.thread
to refer to the core thread
underlying that kernel thread.
Delay the calling EVL thread for a specified amount of time, such thread sleeps without consuming any CPU.
The delay value (relative timeout value). The special value EVL_INFINITE
means infinite sleep, in which case the thread can resume only if
forcibly unblocked by a call to evl_unblock_thread().
Returns zero after a complete sleep, or -EINTR if the call was forcibly unblocked.
Block the calling EVL thread until a given date.
The wake up date (absolute timeout value), which is implicitly based
on the monotonic clock evl_mono_clock
.
Returns zero after a complete sleep, or -EINTR if the call was forcibly unblocked.
Forcibly unblock the thread referred to by thread
. In other words,
the blocking system call is forced to fail, and as a result the target
thread receives the -EINTR error on return. If the thread is not
blocked, this call is a nop.
The descriptor of the EVL thread to unblock.
A bitmask which gives additional information to the thread
about the reason why it was forcibly unblocked. In the common case, reason
should be zero. A non-zero value contains a flag bit matching a
particular
situation,
which translates to a specific error status.
Running a periodic work loop is common practice for real-time
applications. evl_set_period()
enables the calling thread’s private periodic timer by programming its
first release point and its period in the processor time line.
Subsequent calls to evl_wait_period() delay the caller until the next periodic release point in the
timeline is reached. In other words, the periodic work takes place
between two invocations of evl_wait_period(), and such work must not last longer than the
planned period
. Whenever a periodic thread does not call
evl_wait_period() soon enough to
consume the latest notification before the current period ends, an
overrun is said to occur.
The descriptor of the EVL clock device which should be used for timings.
You would use &evl_mono_clock
for a monotonic clock based on the clock
device the EVL core provides.
The initial (absolute) date of the first release point, based on
clock
. The caller is delayed by the first call to
evl_wait_period() until this
point is reached. If idate
equals EVL_INFINITE
, the first release
point is set to period
nanoseconds after the current date.
The period of the thread, based on the clock
unit. Passing
EVL_INFINITE
can be used to stop the caller’s periodic timer, leaving
periodic mode.
Zero is returned upon success, otherwise:
-ETIMEDOUT is returned if idate
is different from EVL_INFINITE
and
represents a date in the past.
-EINVAL is returned if period
is different from EVL_INFINITE but
shorter than the monotonic clock gravity value.
-EPERM is returned if the caller is not an EVL thread.
Block the caller until the next periodic release point in the processor time line. This call is paired with evl_set_period() which sets the period. This call detects missed wake ups, aka overruns.
If non-NULL, the count of pending overruns is copied to that address unless -EINTR was received (see errors below). The copied value is non-zero if -ETIMEDOUT is returned, zero otherwise.
Zero is returned upon success, otherwise:
-EAGAIN is returned if the caller did not set the period using evl_set_period().
-EINTR is returned if the caller was forcibly unblocked by a call to evl_thread_unblock() before the release point was reached. The overrun count is meaningless in this case.
-ETIMEDOUT is returned if the caller has overrun, which indicates
that one or more previous release points have been missed. If
overruns_r
is valid, the count of pending overruns is copied to
the memory location.
Return the EVL core thread descriptor of the caller. NULL is returned if the caller is not an EVL thread.
Both user and kernel space threads would receive a non-NULL pointer. Common Linux threads would receive NULL.