mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Ryan Gardner <ryan.p.gardner@boeing.com>
To: musl@lists.openwall.com
Cc: Ryan Ward <ryan.c.ward3@boeing.com>
Subject: [musl] [PATCH 2/3 libc-test] functional:time:timer_delete test
Date: Tue,  5 Nov 2024 22:44:36 +0000	[thread overview]
Message-ID: <20241105224437.67-2-ryan.p.gardner@boeing.com> (raw)
In-Reply-To: <20241105224437.67-1-ryan.p.gardner@boeing.com>

From: Ryan Ward <ryan.c.ward3@boeing.com>

Testing of the musl API against the POSIX 2008 standard, which has
removed the requirement for returning EINVAL upon receiving an invalid
timer_id, and simply classifies it as undefined behavior.

Tests added:
- Deleting an unarmed timer
- Deleting an armed timer
- Deleting a timer that has been passed in the SIGEV_THREAD flag
- Deleting a completed timer
- Deleting, recreating, and deleting a timer

References:
- https://pubs.opengroup.org/onlinepubs/9699919799/functions/timer_delete.html

Signed-off-by: Ryan Ward <ryan.c.ward3@boeing.com>
---
 src/functional/timer_delete.c | 123 ++++++++++++++++++++++++++++++++++
 1 file changed, 123 insertions(+)
 create mode 100644 src/functional/timer_delete.c

diff --git a/src/functional/timer_delete.c b/src/functional/timer_delete.c
new file mode 100644
index 0000000..810a4d1
--- /dev/null
+++ b/src/functional/timer_delete.c
@@ -0,0 +1,123 @@
+/*
+ * timer_delete.c unit test
+ */
+#include "test.h"
+#include <errno.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define TEST(c, ...) ((c) || (t_error(#c " failed: " __VA_ARGS__), 0))
+
+#define SLEEP_NANO 500000
+#define TIMER_SPEC \
+	(struct itimerspec) \
+	{ \
+		.it_value = {0, SLEEP_NANO}, .it_interval = { 0, 0 } \
+	}
+
+typedef struct {
+	clockid_t clock;
+	int armed;
+} timer_params;
+
+static void dummy_signal_handler(int signum) {}
+
+static void delete_timer(const timer_params *timer)
+{
+	timer_t timer_id = 0;
+	if (timer_create(timer->clock, NULL, &timer_id) < 0) {
+		t_error("Failed to created SIGEV_SIGNAL timer: %s\n", strerror(errno));
+		return;
+	}
+
+	if (timer->armed) {
+		if (timer_settime(timer_id, 0, &TIMER_SPEC, NULL) < 0) {
+			t_error("Failed to arm SIGEV_SIGNAL timer: %s\n", strerror(errno));
+		}
+	}
+
+	TEST(timer_delete(timer_id) == 0,
+	     "Failed to delete SIGEV_SIGNAL timer: %d\n", timer_id);
+}
+
+static void delete_thread_timer(const timer_params *timer)
+{
+	timer_t timer_id = 0;
+	struct sigevent sigev = {.sigev_signo = SIGRTMIN,
+	                         .sigev_notify = SIGEV_THREAD};
+
+	if (timer_create(timer->clock, &sigev, &timer_id) < 0) {
+		t_error("Failed to create SIGEV_THREAD timer: %s\n", strerror(errno));
+		return;
+	}
+
+	if (timer->armed) {
+		if (timer_settime(timer_id, 0, &TIMER_SPEC, NULL) < 0) {
+			t_error("Failed to arm SIGEV_THREAD timer: %s\n", strerror(errno));
+		}
+	}
+
+	TEST(timer_delete(timer_id) == 0,
+	     "Failed to delete SIGEV_THREAD timer: %d\n", timer_id);
+}
+
+static void delete_completed_timer(timer_t timer_id, clockid_t clock)
+{
+	struct sigaction sa = {.sa_handler = dummy_signal_handler};
+
+	sigemptyset(&sa.sa_mask);
+	if (sigaction(SIGALRM, &sa, NULL) == -1) {
+		t_error("Error setting up signal handler: %s\n", strerror(errno));
+		return;
+	}
+
+	if (timer_create(clock, NULL, &timer_id) < 0) {
+		t_error("Failed to created SIGEV_SIGNAL timer: %s\n", strerror(errno));
+		return;
+	}
+
+	if (timer_settime(timer_id, 0, &TIMER_SPEC, NULL) < 0) {
+		t_error("Failed to arm SIGEV_SIGNAL timer: %s\n", strerror(errno));
+	}
+
+	// Wait for SIGARLM
+	pause();
+
+	TEST(timer_delete(timer_id) == 0,
+	     "Failed to delete SIGEV_SIGNAL timer: %d\n", timer_id);
+}
+
+int main(void)
+{
+	static const clockid_t clocks_to_test[] = {CLOCK_REALTIME, CLOCK_MONOTONIC};
+	static const size_t num_clocks =
+	    sizeof(clocks_to_test) / sizeof(*clocks_to_test);
+
+	for (int clock = 0; clock < num_clocks; ++clock) {
+		const timer_params unarmed_timer = {0, clocks_to_test[clock]};
+		const timer_params armed_timer = {1, clocks_to_test[clock]};
+		// Delete an unarmed timer
+		delete_timer(&unarmed_timer);
+
+		// Delete an armed timer
+		delete_timer(&armed_timer);
+
+		// Delete a thread unarmed timer
+		delete_thread_timer(&unarmed_timer);
+
+		// Delete a thread armed timer
+		delete_thread_timer(&armed_timer);
+
+		// Let the timer run out, and delete
+		timer_t timer_id = 0;
+		delete_completed_timer(timer_id, clocks_to_test[clock]);
+
+		// Retry the same operation with the same timer_id (should succeed)
+		delete_completed_timer(timer_id, clocks_to_test[clock]);
+	}
+
+	return t_status;
+}
-- 
2.34.1


  reply	other threads:[~2024-11-05 22:45 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-05 22:44 [musl] [PATCH 1/3 libc-test] functional:time:clock_nanosleep test Ryan Gardner
2024-11-05 22:44 ` Ryan Gardner [this message]
2024-11-05 22:44 ` [musl] [PATCH 3/3 libc-test] functional:time:timer_settime test Ryan Gardner
2024-11-06  7:38 ` [musl] [PATCH 1/3 libc-test] functional:time:clock_nanosleep test Szabolcs Nagy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241105224437.67-2-ryan.p.gardner@boeing.com \
    --to=ryan.p.gardner@boeing.com \
    --cc=musl@lists.openwall.com \
    --cc=ryan.c.ward3@boeing.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).