The target platform can provide particular clock chips and/or clock source drivers in addition to the architecture-specific ones. For instance, some device on a PCI bus could provide a timer which the application wants to use for timing its threads, in addition to the architected timer found on ARM64 and some ARM-based SoCs. The timer hardware would be accessed through the EVL core via a dedicated kernel driver.
EVL’s clock element ensures all clock drivers present the same interface to applications in user-space. In addition, the clock element can export individual software timers to applications which comes in handy for running periodic loops or waiting for oneshot events on a specific time base.
Some built-in clocks are pre-defined by the EVL core for reading the monotonic and wallclock time of the system.
EVL abstracts clock event devices and clock sources (timekeeping hardware) into a single clock element.
This call is the EVL equivalent of the POSIX clock_gettime(3) service, for reading the time from a specified EVL clock. It reads the current time maintained by the EVL clock, which is returned as counts of seconds and microseconds since the clock’s epoch.
The clock file descriptor, which can be:
any valid file descriptor received as a result of opening a clock
device in /dev/evl/clock
.
the identifier of a built-in EVL clock, such as EVL_CLOCK_MONOTONIC
or
EVL_CLOCK_REALTIME
.
A pointer to a timespec structure which should receive the time stamp.
evl_read_clock() writes the timestamp to tp then returns zero on success, otherwise:
-EBADF if clockfd is neither a built-in clock identifier or a valid file descriptor.
-ENOTTY if clockfd does not refer to an EVL clock device.
-EFAULT if tp points to invalid memory.
This call is the EVL equivalent of the POSIX clock_settime(3) service, for setting the time of a specified EVL clock.
The clock file descriptor, which can be:
any valid file descriptor received as a result of opening a clock
device in /dev/evl/clock
.
the identifier of a built-in EVL clock, such as EVL_CLOCK_MONOTONIC
or
EVL_CLOCK_REALTIME
.
A pointer to a timespec structure which should receive the time stamp.
evl_set_clock() returns zero and the clock is set to the specified time on success, otherwise:
-EINVAL if the time specification referred to by ts is invalid
(e.g. ts->tv_nsec
not in the [0..1e9] range).
-EBADF if clockfd is neither a built-in clock identifier or a valid file descriptor.
-EPERM if the caller does not have the permission to set some built-in clock via clock_settime(3). See note.
-ENOTTY if clockfd does not refer to an EVL clock device.
-EFAULT if tp points to invalid memory.
Setting EVL_CLOCK_MONOTONIC
or EVL_CLOCK_REALTIME
may imply a
transition to the in-band execution stage as
clock_settime()
is called internally for carrying out the request.
This call is the EVL equivalent of the POSIX clock_getres(3) service, for reading the resolution of a specified EVL clock. It returns this value as counts of seconds and microseconds. The resolution of clocks depends on the implementation and cannot be configured.
The clock file descriptor, which can be:
any valid file descriptor received as a result of opening a clock
device in /dev/evl/clock
.
the identifier of a built-in EVL clock, such as EVL_CLOCK_MONOTONIC
or
EVL_CLOCK_REALTIME
.
A pointer to a timespec structure which should receive the resolution.
evl_get_clock_resolution() writes the resolution to tp then returns zero on success, otherwise:
-EBADF if clockfd is neither a built-in clock identifier or a valid file descriptor.
-ENOTTY if clockfd does not refer to an EVL clock device.
-EFAULT if tp points to invalid memory.
Setting EVL_CLOCK_MONOTONIC
or EVL_CLOCK_REALTIME
may imply a
transition to the in-band execution stage as
clock_getres(3)
is called internally for carrying out the request.
This call is the EVL equivalent of the POSIX clock_nanosleep(3) service, for blocking the caller until an arbitrary date expires on a specified EVL clock. Unlike its POSIX counterpart, evl_sleep_until() only accepts absolute timeout specifications though.
The clock file descriptor, which can be:
any valid file descriptor received as a result of opening a clock
device in /dev/evl/clock
.
the identifier of a built-in EVL clock, such as EVL_CLOCK_MONOTONIC
or
EVL_CLOCK_REALTIME
.
A pointer to a timespec structure which specifies the wake up date.
evl_sleep_until() blocks the caller until the wake up date expires then returns zero on success, otherwise:
-EBADF if clockfd is neither a built-in clock identifier or a valid file descriptor.
-ENOTTY if clockfd does not refer to an EVL clock device.
-EFAULT if timeout points to invalid memory.
-EINTR if the call was interrupted by an in-band signal, or forcibly unblocked by the EVL core.
This call puts the caller to sleep until a count of microseconds has
elapsed. evl_usleep() invokes
evl_sleep_until() for sleeping
until the delay expires on the EVL_CLOCK_MONOTONIC
clock.
The count of microseconds to sleep for. This value should not exceed 1000000 (i.e. one second timeout). If zero, the call has no effect and returns immediately with a success status.
evl_usleep() blocks the caller until the delay expires then returns zero on success, otherwise:
-EINTR if the call was interrupted by an in-band signal, or forcibly unblocked by the EVL core.
-EINVAL if usecs is greater than 1000000.
EVL defines two built-in clocks, you can pass any of the following identifiers to EVL calls which ask for a clock file descriptor (usually noted as clockfd):
EVL_CLOCK_MONOTONIC
is identical to the CLOCK_MONOTONIC
POSIX
clock, which is a monotonically increasing clock that cannot be set
and represents time since some unspecified starting point (aka the
epoch). This identifier has the same meaning than a file descriptor
opened on /dev/evl/clock/monotonic
.
EVL_CLOCK_REALTIME
is identical to the CLOCK_REALTIME
POSIX
clock, which is a non-monotonic wall clock which can be manually set
to an arbitrary value with proper privileges, and can also be
subject to dynamic adjustements by the NTP system. This identifier
has the same meaning than a file descriptor opened on
/dev/evl/clock/realtime
.
If you are to measure the elapsed time between two events, you
definitely want to use EVL_CLOCK_MONOTONIC
.