evl_udelay() was an annoying misnomer for people with kernel
development background, as this relates to a busy wait loop, not to a
sleeping call, which evl_udelay() actually was.
Rename this call to evl_usleep(), converging to the glibc signature
for usleep(3) in the same move.
Some tests might fail due to a lack of kernel support, such as a
missing driver which have to to be involved for running such
tests. Introduce the EXIT_NO_SUPPORT code for this case, to be
distinguished by the test runner from a functional failure.
Replace -a (abort-on-switch) with -K (keep-going upon
switch). Aborting becomes the default setting upon unexpected switch
to in-band mode of the responder thread, in order to prevent any
misinterpretation of broken results obtained from a broken set up.
Let the user generate any background noise as/if required. We simply
cannot approximate the typical load of the target system in a reliable
manner with a fixed dd-like loop.
Measure response time to GPIO events sent by a remote Zephyr-based
latency monitor (latmon). This monitor collects then sends the latency
data over a network connection to the latmus front-end which displays
the results received:
[Linux device under test running latmus] <--+
|
^ | (GPIO ack) |
| | | TCP/IP network connection
| | | (control & data samples)
| (GPIO pulse) v |
|
[Zephyr-based device running latmon] <--+
The generic latency monitor code running the measurement loop is
available from the zephyr/ directory. This support comes with a Zephyr
device tree patch for enabling this monitor on NXP's FRDM-K64F
development board.
Just like DECLARE_EVL_TUBE_CANISTER() should be used explicitly for
declaring a new canister type for a local tube, the same should be
done with DECLARE_EVL_TUBE_CANISTER_REL() for a shared tube. Stop
calling the latter implicitly from DECLARE_EVL_TUBE_REL(), to remain
consist with DECLARE_EVL_TUBE() usage.
A lighweight, lockless multi-reader/multi-writer FIFO with a
base-offset variant which can work over a memory segment shared
between processes. Scalar data or simple (small!) aggregates are
conveyed though a tube inside canisters which exactly fit their type.
By design, a tube is meant to be a basic, spartan mechanism: it
imposes no usage policy whatsoever on users.
As a result, a tube is strictly non-blocking, it solely detects and
notifies the caller on return about empty input (no message in) and
output contention (no buffer space for output). If required, the
caller can implement blocking states, typically with a pair of EVL
semaphores, e.g. setting up a tube conveying integers which supports
blocking mode:
DECLARE_EVL_TUBE_CANISTER(canister_type, int); /* defines struct canister_type */
DECLARE_EVL_TUBE(tube_type, cannister_type) tube;
struct cannister_type items[1024];
evl_init_tube(&tube, items, 1024);
evl_new_sem(&in, ...);
evl_new_sem_any(&out, CLOCK_MONOTONIC, tube.max_items, ...);
evl_get_sem(&in, ...); @ evl_get_sem(&out);
evl_tube_receive(&tube, ...); @ evl_tube_send(&tube, ...);
evl_put_sem(&out); @ evl_put_sem(&in, ...);
Returns version information about the running EVL interface including
the API and kernel ABI levels. A negative ABI level denotes the EVL
shim layer (eshi).
Stress load running in parallel to this test might be high enough to
have udelay() actually skipped by the EVL core since the sleep_until
(absolute) form is used internally, preventing evl_schedule() from
ever being called, which in turn skip the PP boost for the caller.
This has been observed on qemu-aarch64 under extreme load.
Increase the delay to 5ms.