Module Name:    src
Committed By:   jruoho
Date:           Wed May 19 19:17:08 UTC 2010

Modified Files:
        src/distrib/sets/lists/tests: mi
        src/tests/syscall: Makefile
Added Files:
        src/tests/syscall: t_timer.c

Log Message:
Add a simple test for timer_create(2) / sigevent(3).
Case for SIGEV_THREAD commented out.


To generate a diff of this commit:
cvs rdiff -u -r1.74 -r1.75 src/distrib/sets/lists/tests/mi
cvs rdiff -u -r1.8 -r1.9 src/tests/syscall/Makefile
cvs rdiff -u -r0 -r1.1 src/tests/syscall/t_timer.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/tests/mi
diff -u src/distrib/sets/lists/tests/mi:1.74 src/distrib/sets/lists/tests/mi:1.75
--- src/distrib/sets/lists/tests/mi:1.74	Sat May 15 09:00:53 2010
+++ src/distrib/sets/lists/tests/mi	Wed May 19 19:17:08 2010
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.74 2010/05/15 09:00:53 njoly Exp $
+# $NetBSD: mi,v 1.75 2010/05/19 19:17:08 jruoho Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -201,6 +201,7 @@
 ./usr/libdata/debug/usr/tests/rump/rumpkern/t_modlinkset.debug		tests-syscall-debug	debug,atf
 ./usr/libdata/debug/usr/tests/syscall					tests-syscall-debug
 ./usr/libdata/debug/usr/tests/syscall/t_cmsg.debug			tests-syscall-debug	debug,atf
+./usr/libdata/debug/usr/tests/syscall/t_timer.debug			tests-syscall-debug	debug,atf
 ./usr/libdata/debug/usr/tests/util					tests-util-debug
 ./usr/libdata/debug/usr/tests/util/df					tests-util-debug
 ./usr/libdata/debug/usr/tests/util/df/h_df.debug			tests-util-debug	debug
@@ -1124,6 +1125,7 @@
 ./usr/tests/syscall				tests-syscall-tests
 ./usr/tests/syscall/Atffile			tests-syscall-tests	atf
 ./usr/tests/syscall/t_cmsg			tests-syscall-tests	atf
+./usr/tests/syscall/t_timer			tests-syscall-tests	atf
 ./usr/tests/util				tests-util-tests
 ./usr/tests/util/Atffile			tests-util-tests
 ./usr/tests/util/awk				tests-util-tests

Index: src/tests/syscall/Makefile
diff -u src/tests/syscall/Makefile:1.8 src/tests/syscall/Makefile:1.9
--- src/tests/syscall/Makefile:1.8	Thu Nov 26 17:33:23 2009
+++ src/tests/syscall/Makefile	Wed May 19 19:17:08 2010
@@ -1,10 +1,10 @@
-# $NetBSD: Makefile,v 1.8 2009/11/26 17:33:23 pooka Exp $
+# $NetBSD: Makefile,v 1.9 2010/05/19 19:17:08 jruoho Exp $
 
 .include <bsd.own.mk>
 
 TESTSDIR=	${TESTSBASE}/syscall
 
-TESTS_C+=	t_cmsg
+TESTS_C+=	t_cmsg t_timer
 
 LDADD+=	-lrumpnet_local -lrumpnet_net -lrumpnet
 LDADD+=	-lrumpvfs -lrump -lrumpuser -lpthread

Added files:

Index: src/tests/syscall/t_timer.c
diff -u /dev/null src/tests/syscall/t_timer.c:1.1
--- /dev/null	Wed May 19 19:17:08 2010
+++ src/tests/syscall/t_timer.c	Wed May 19 19:17:08 2010
@@ -0,0 +1,324 @@
+/*	$NetBSD: t_timer.c,v 1.1 2010/05/19 19:17:08 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2010 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include <atf-c.h>
+
+#include "../h_macros.h"
+
+static void	timer_signal_create(clockid_t, int);
+static void	timer_signal_handler(int, siginfo_t *, void *);
+static int	timer_wait(time_t);
+
+#if 0
+/*
+ * XXX: SIGEV_THREAD is not yet supported.
+ */
+static void	timer_thread_create(clockid_t);
+static void	timer_thread_handler(sigval_t);
+#endif
+
+static timer_t t;
+static bool error;
+static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
+
+ATF_TC(timer_create_bogus);
+ATF_TC_HEAD(timer_create_bogus, tc)
+{
+
+	/* Cf. PR lib/42434. */
+	atf_tc_set_md_var(tc, "descr",
+	    "Checks timer_create(2)'s error checking");
+}
+
+ATF_TC_BODY(timer_create_bogus, tc)
+{
+	struct sigevent evt;
+
+	(void)memset(&evt, 0, sizeof(struct sigevent));
+
+	evt.sigev_signo = -1;
+	evt.sigev_notify = SIGEV_SIGNAL;
+
+	if (timer_create(CLOCK_REALTIME, &evt, &t) == 0)
+		goto fail;
+
+	evt.sigev_signo = SIGUSR1;
+	evt.sigev_notify = SIGEV_THREAD + 100;
+
+	if (timer_create(CLOCK_REALTIME, &evt, &t) == 0)
+		goto fail;
+
+	evt.sigev_signo = SIGUSR1;
+	evt.sigev_value.sival_int = 0;
+	evt.sigev_notify = SIGEV_SIGNAL;
+
+	if (timer_create(CLOCK_REALTIME + 100, &evt, &t) == 0)
+		goto fail;
+
+	t = 0;
+
+	return;
+
+fail:
+	atf_tc_fail("timer_create() successful with bogus values");
+}
+
+ATF_TC(timer_create_signal);
+ATF_TC_HEAD(timer_create_signal, tc)
+{
+
+	atf_tc_set_md_var(tc, "descr",
+	    "Checks timer_create(2) and sigevent(3), SIGEV_SIGNAL");
+}
+
+ATF_TC_BODY(timer_create_signal, tc)
+{
+	int i, signals[6] = {
+		SIGALRM, SIGIO, SIGPROF, SIGUSR1, SIGUSR2, -1
+	};
+
+	for (i = 0; signals[i] > 0; i++)
+		timer_signal_create(CLOCK_REALTIME, signals[i]);
+}
+
+static void
+timer_signal_create(clockid_t cid, int sig)
+{
+	struct itimerspec tim;
+	struct sigaction act;
+	struct sigevent evt;
+	const char *errstr;
+	sigset_t set;
+
+	error = true;
+
+	(void)memset(&evt, 0, sizeof(struct sigevent));
+	(void)memset(&act, 0, sizeof(struct sigaction));
+	(void)memset(&tim, 0, sizeof(struct itimerspec));
+
+	act.sa_flags = SA_SIGINFO;
+	act.sa_sigaction = timer_signal_handler;
+
+	(void)sigemptyset(&act.sa_mask);
+
+	if (sigaction(sig, &act, NULL) != 0) {
+		errstr = "sigaction()";
+		goto fail;
+	}
+
+	(void)sigemptyset(&set);
+	(void)sigaddset(&set, sig);
+
+	if (sigprocmask(SIG_SETMASK, &set, NULL) != 0) {
+		errstr = "sigprocmask()";
+		goto fail;
+	}
+
+	evt.sigev_signo = sig;
+	evt.sigev_value.sival_ptr = &t;
+	evt.sigev_notify = SIGEV_SIGNAL;
+
+	if (timer_create(cid, &evt, &t) != 0) {
+		errstr = "timer_create()";
+		goto fail;
+	}
+
+	tim.it_value.tv_sec = 0;
+	tim.it_value.tv_nsec = 1000 * 1000;
+
+	if (timer_settime(t, 0, &tim, NULL) != 0) {
+		errstr = "timer_settime()";
+		goto fail;
+	}
+
+	if (sigprocmask(SIG_UNBLOCK, &set, NULL) != 0) {
+		errstr = "sigprocmask()";
+		goto fail;
+	}
+
+	errno = timer_wait(1);
+
+	if (errno != 0) {
+		errstr = "timer_wait()";
+		goto fail;
+	}
+
+	return;
+
+fail:
+	atf_tc_fail_errno("%s failed (sig %d, clock %d)", errstr, sig, cid);
+}
+
+static void
+timer_signal_handler(int signo, siginfo_t *si, void *osi)
+{
+	timer_t *tp;
+
+	if (pthread_mutex_lock(&mtx) != 0)
+		return;
+
+	tp = si->si_value.sival_ptr;
+
+	if (*tp == t)
+		error = false;
+
+	(void)pthread_cond_signal(&cond);
+	(void)pthread_mutex_unlock(&mtx);
+	(void)signal(signo, SIG_IGN);
+}
+
+static int
+timer_wait(time_t wait)
+{
+	struct timespec ts;
+	int rv;
+
+	rv = pthread_mutex_lock(&mtx);
+
+	if (rv != 0)
+		return rv;
+
+	errno = 0;
+
+	if (clock_gettime(CLOCK_REALTIME, &ts) != 0) {
+
+		if (errno == 0)
+			errno = EFAULT;
+
+		return errno;
+	}
+
+	ts.tv_sec += wait;
+	rv = pthread_cond_timedwait(&cond, &mtx, &ts);
+
+	if (rv != 0)
+		return rv;
+
+	rv = pthread_mutex_unlock(&mtx);
+
+	if (rv != 0)
+		return rv;
+
+	if (error != false)
+		return EPROCUNAVAIL;
+
+	return timer_delete(t);
+}
+
+#if 0
+ATF_TC(timer_create_thread);
+ATF_TC_HEAD(timer_create_thread, tc)
+{
+
+	atf_tc_set_md_var(tc, "descr",
+	    "Checks timer_create(2) and sigevent(3), SIGEV_THREAD");
+}
+
+ATF_TC_BODY(timer_create_thread, tc)
+{
+	timer_thread_create(CLOCK_REALTIME);
+}
+
+static void
+timer_thread_create(clockid_t cid)
+{
+	struct itimerspec tim;
+	struct sigevent evt;
+	const char *errstr;
+
+	error = true;
+
+	(void)memset(&evt, 0, sizeof(struct sigevent));
+	(void)memset(&tim, 0, sizeof(struct itimerspec));
+
+	evt.sigev_notify = SIGEV_THREAD;
+	evt.sigev_value.sival_ptr = &t;
+	evt.sigev_notify_function = timer_thread_handler;
+	evt.sigev_notify_attributes = NULL;
+
+	if (timer_create(cid, &evt, &t) != 0) {
+		errstr = "timer_create()";
+		goto fail;
+	}
+
+	tim.it_value.tv_sec = 1;
+	tim.it_value.tv_nsec = 0;
+
+	if (timer_settime(t, 0, &tim, NULL) != 0) {
+		errstr = "timer_settime()";
+		goto fail;
+	}
+
+	errno = timer_wait(3);
+
+	if (errno != 0) {
+		errstr = "timer_wait()";
+		goto fail;
+	}
+
+	return;
+
+fail:
+	atf_tc_fail_errno("%s failed (clock %d)", errstr, cid);
+}
+
+static void
+timer_thread_handler(sigval_t sv)
+{
+	timer_t *tp;
+
+	if (pthread_mutex_lock(&mtx) != 0)
+		return;
+
+	tp = sv.sival_ptr;
+
+	if (*tp == t)
+		error = false;
+
+	(void)pthread_cond_signal(&cond);
+	(void)pthread_mutex_unlock(&mtx);
+}
+#endif
+
+ATF_TP_ADD_TCS(tp)
+{
+
+	ATF_TP_ADD_TC(tp, timer_create_bogus);
+	ATF_TP_ADD_TC(tp, timer_create_signal);
+     /*	ATF_TP_ADD_TC(tp, timer_create_thread); */
+
+	return atf_no_error();
+}

Reply via email to