tests: kernel: pipe: Add concurrency test for zero-length pipes

This commit adds a new test case to the pipe API concurrency tests to
verify the behavior of zero-length pipes. The test ensures that writing
to a zero-length pipe blocks until data is read, and reading from a
zero-length pipe blocks until data is written—unless the pipe is closed,
reset, or the operation times out.

The test creates two pipes with zero-length buffers and spawns a helper
thread that performs complementary read/write operations. The two threads
use the pipe API as their only synchronization mechanism, validating the
correct blocking and wake-up behavior of zero-length pipes under
concurrent access.

Signed-off-by: Måns Ansgariusson <Mansgariusson@gmail.com>
diff --git a/tests/kernel/pipe/pipe_api/src/concurrency.c b/tests/kernel/pipe/pipe_api/src/concurrency.c
index f147e2e..f30e3c7 100644
--- a/tests/kernel/pipe/pipe_api/src/concurrency.c
+++ b/tests/kernel/pipe/pipe_api/src/concurrency.c
@@ -163,3 +163,51 @@
 		"failed t read from pipe");
 	k_thread_join(tid, K_FOREVER);
 }
+
+static volatile bool zero_thread_read;
+static volatile bool zero_thread_write;
+static void zero_thread_read_write(void *arg1, void *arg2, void *arg3)
+{
+	uint8_t tmp[DUMMY_DATA_SIZE];
+	struct k_pipe *input = (struct k_pipe *)arg1;
+	struct k_pipe *output = (struct k_pipe *)arg2;
+
+	memset(tmp, 0xBB, sizeof(tmp));
+
+	zero_thread_read = true;
+	zassert_true(k_pipe_read(input, tmp, sizeof(tmp), K_FOREVER) == sizeof(tmp),
+	      "Failed to read from pipe");
+	zero_thread_write = true;
+	zassert_true(k_pipe_write(output, tmp, sizeof(tmp), K_FOREVER) == sizeof(tmp),
+	      "Failed to write to pipe");
+}
+
+ZTEST(k_pipe_concurrency, test_zero_size_pipe_read_write)
+{
+	k_tid_t tid;
+	struct k_pipe input_pipe;
+	struct k_pipe output_pipe;
+	uint8_t input[DUMMY_DATA_SIZE];
+	uint8_t output[DUMMY_DATA_SIZE];
+
+	memset(input, 0xAA, sizeof(input));
+	memset(output, 0xCC, sizeof(output));
+	k_pipe_init(&input_pipe, NULL, 0);
+	k_pipe_init(&output_pipe, NULL, 0);
+
+	tid = k_thread_create(&thread, stack, K_THREAD_STACK_SIZEOF(stack),
+		zero_thread_read_write, &input_pipe, &output_pipe, NULL, K_PRIO_COOP(0), 0,
+		K_NO_WAIT);
+
+	zassert_true(sizeof(input) == k_pipe_write(&input_pipe, input, sizeof(input), K_FOREVER),
+	      "Failed to write to pipe");
+	zassert_true(sizeof(output) == k_pipe_read(&output_pipe, output, sizeof(output), K_FOREVER),
+	      "Failed to read from pipe");
+	zassert_true(memcmp(input, output, sizeof(input)) == 0,
+		"Unexpected data received from pipe");
+
+	zassert_true(zero_thread_read && zero_thread_write,
+		"Thread did not execute expected read/write operations");
+
+	k_thread_join(tid, K_FOREVER);
+}