perf(tftf): don't use waitms() for events testing
Waiting for wall time on FVP takes longer than the desired time. As a
result this test takes a seemingly very long (over 30 seconds!) and is
sometimes indistinguishable from hanging. Additionally, it is a tftf
self test so the chances of it ever going wrong are practically zero.
Decouple the test from time and use more primitive synchronisation to
maintain the same function. Since the primary waits for all secondaries
to enter the test, we can be fairly certain that at least one has
proceeded a little further and is waiting for an event by the time the
primary has caught up and we don't need the delay. Then the other
delays can be removed by having the secondaries wait on non-event API
event before waiting on the event.
Change-Id: I958595b93030596633bbd08b2369ecdffe34d6d3
Signed-off-by: Boyan Karatotev <boyan.karatotev@arm.com>
diff --git a/tftf/tests/framework_validation_tests/test_validation_events.c b/tftf/tests/framework_validation_tests/test_validation_events.c
index e229b17..172c409 100644
--- a/tftf/tests/framework_validation_tests/test_validation_events.c
+++ b/tftf/tests/framework_validation_tests/test_validation_events.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2025, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -17,6 +17,8 @@
static event_t cpu_has_entered_test[PLATFORM_CORE_COUNT];
static event_t test_is_finished;
+volatile bool last_event_ready;
+
static test_result_t non_lead_cpu_fn(void)
{
unsigned int mpid = read_mpidr_el1() & MPID_MASK;
@@ -29,10 +31,10 @@
/*
* Wait for lead CPU's signal before exiting the test.
- * Introduce a delay so that the lead CPU will send the event before the
- * non-lead CPUs wait for it.
+ * Wait for the lead CPU to send the event before the non-lead CPUs wait
+ * for it.
*/
- waitms(500);
+ while (!last_event_ready);
tftf_wait_for_event(&test_is_finished);
return TEST_RESULT_SUCCESS;
@@ -43,7 +45,7 @@
*
* This test exercises the events API.
* - It creates a sequence of events sending and receiving. The order of
- * operations is ensured by inserting delays at strategic points.
+ * operations is ensured by synchronizing at strategic points.
* - It tests the communication in both directions (i.e. from CPUx to CPUy and
* vice versa).
* - It tests that it doesn't matter whether CPUx waits for the event first
@@ -64,6 +66,9 @@
unsigned int cpus_count;
int psci_ret;
+ /* initialise as not ready */
+ last_event_ready = false;
+
lead_cpu = read_mpidr_el1() & MPID_MASK;
/*
@@ -104,19 +109,19 @@
}
/*
- * Introduce a delay so that the non-lead CPUs will wait for this event
- * before the lead CPU sends it.
+ * Send the event to half of the CPUs. Some should already be waiting,
+ * as they signalled entering the test.
*/
- waitms(500);
- /* Send the event to half of the CPUs */
cpus_count = PLATFORM_CORE_COUNT / 2;
tftf_send_event_to(&lead_cpu_event, cpus_count);
- waitms(500);
/* Send the event to the other half of the CPUs */
tftf_send_event_to(&lead_cpu_event, PLATFORM_CORE_COUNT - cpus_count);
/* Signal termination of the test to all CPUs */
tftf_send_event_to_all(&test_is_finished);
+ /* Signal the last event has been sent so secondaries can wait() */
+ last_event_ready = true;
+
return TEST_RESULT_SUCCESS;
}