Commit a777889f authored by Emil Dahl Juhl's avatar Emil Dahl Juhl Committed by Benjamin Cabé
Browse files

tests: rtio: rtio_api: add relaxed await sqe test



Expand the test case for RTIO_OP_AWAIT to also cover the relaxed variant
where just the SQE chain is paused until completion, and the rtio_iodev
can serve unrelated SQEs meanwhile.

Signed-off-by: default avatarEmil Dahl Juhl <emil@s16s.ai>
parent 5b7c462c
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
@@ -949,9 +949,97 @@ void test_rtio_await_(struct rtio *rtio0, struct rtio *rtio1)
	rtio_cqe_release(rtio1, cqe);
}

/**
 * @brief Test await operations handled purely by the executor
 *
 * Ensures we can pause just one SQE chain using the AWAIT operation, letting the rtio_iodev serve
 * other sequences during the wait, and finally resume the executor by calling rtio_sqe_signal().
 */
void test_rtio_await_executor_(struct rtio *rtio0, struct rtio *rtio1)
{
	int res;
	int32_t userdata[4] = {0, 1, 2, 3};
	struct rtio_sqe *await_sqe;
	struct rtio_sqe *sqe;
	struct rtio_cqe *cqe;

	rtio_iodev_test_init(&iodev_test_await0);

	/* Prepare a NOP->AWAIT chain on rtio0 to verify the blocking behavior of AWAIT */
	sqe = rtio_sqe_acquire(rtio0);
	zassert_not_null(sqe, "Expected a valid sqe");
	rtio_sqe_prep_nop(sqe, &iodev_test_await0, &userdata[0]);
	sqe->flags = RTIO_SQE_CHAINED;

	await_sqe = rtio_sqe_acquire(rtio0);
	zassert_not_null(await_sqe, "Expected a valid sqe");
	rtio_sqe_prep_await_executor(await_sqe, RTIO_PRIO_LOW, &userdata[1]);
	await_sqe->flags = 0;

	/*
	 * Prepare another NOP on rtio0, to verify that while the await is busy, the executor
	 * can process an unconnected operation
	 */
	sqe = rtio_sqe_acquire(rtio0);
	zassert_not_null(sqe, "Expected a valid sqe");
	rtio_sqe_prep_nop(sqe, &iodev_test_await0, &userdata[3]);
	sqe->flags = 0;

	/* Prepare a NOP sqe on rtio1 */
	sqe = rtio_sqe_acquire(rtio1);
	zassert_not_null(sqe, "Expected a valid sqe");
	rtio_sqe_prep_nop(sqe, &iodev_test_await0, &userdata[2]);
	sqe->prio = RTIO_PRIO_HIGH;
	sqe->flags = 0;

	/* Submit the rtio0 sequence and make sure it reaches the AWAIT sqe */
	TC_PRINT("Submitting await sqe from rtio0\n");
	res = rtio_submit(rtio0, 0);
	zassert_ok(res, "Submission failed");

	TC_PRINT("Wait for nop sqe from rtio0 completed\n");
	cqe = rtio_cqe_consume_block(rtio0);
	zassert_not_null(sqe, "Expected a valid sqe");
	zassert_equal(cqe->userdata, &userdata[0]);
	rtio_cqe_release(rtio0, cqe);

	/* Submit rtio1 sequence and ensure it completes while rtio0 is paused at the AWAIT */
	TC_PRINT("Submitting sqe from rtio1\n");
	res = rtio_submit(rtio1, 0);
	zassert_ok(res, "Submission failed");

	TC_PRINT("Ensure sqe from rtio1 completes\n");
	cqe = rtio_cqe_consume_block(rtio1);
	zassert_not_null(cqe, "Expected a valid cqe");
	zassert_equal(cqe->userdata, &userdata[2]);
	rtio_cqe_release(rtio1, cqe);

	/* Verify that rtio0 processes the freestanding NOP during the await */
	TC_PRINT("Ensure freestanding NOP completes while await is busy\n");
	cqe = rtio_cqe_consume_block(rtio0);
	zassert_not_null(cqe, "Expected a valid cqe");
	zassert_equal(cqe->userdata, &userdata[3]);
	rtio_cqe_release(rtio1, cqe);

	/* Make sure rtio0 is still paused at the AWAIT and finally complete it */
	TC_PRINT("Ensure await_sqe is not completed unintentionally\n");
	cqe = rtio_cqe_consume(rtio0);
	zassert_equal(cqe, NULL, "Expected no valid cqe");

	TC_PRINT("Signal await sqe from rtio0\n");
	rtio_sqe_signal(await_sqe);

	TC_PRINT("Ensure sqe from rtio0 completed\n");
	cqe = rtio_cqe_consume_block(rtio0);
	zassert_not_null(cqe, "Expected a valid cqe");
	zassert_equal(cqe->userdata, &userdata[1]);
	rtio_cqe_release(rtio0, cqe);
}

ZTEST(rtio_api, test_rtio_await)
{
	test_rtio_await_(&r_await0, &r_await1);
	test_rtio_await_executor_(&r_await0, &r_await1);
}

static void *rtio_api_setup(void)