Module Name:    src
Committed By:   jmmv
Date:           Mon Jul 19 10:31:46 UTC 2010

Modified Files:
        src/tests/lib/libpthread: t_sem.c

Log Message:
Split the before_start test in two: one that does not use threads and one
that does.  The former works all the time but the latter gets consistently
stuck on amd64.  Mark the latter as an expected timeout (should be a "race
condition" test, but atf does not have such a thing yet[1]).

This clears the test failures, at least, under anita running NetBSD/i386.

>From pooka@: this could well be because calling sem_post(3) from a signal
handler can't possibly do the right thing with the pthread implementation.
However, according to signal(7), sem_post(3) is signal-async safe...

While here, program alarms using a timeout shorter than 1 second to speed
up the execution of the tests.

1: Good thing is I finally understand what a "race condition" test looks
like, I believe.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/tests/lib/libpthread/t_sem.c

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

Modified files:

Index: src/tests/lib/libpthread/t_sem.c
diff -u src/tests/lib/libpthread/t_sem.c:1.2 src/tests/lib/libpthread/t_sem.c:1.3
--- src/tests/lib/libpthread/t_sem.c:1.2	Sun Jul 18 22:30:55 2010
+++ src/tests/lib/libpthread/t_sem.c	Mon Jul 19 10:31:46 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: t_sem.c,v 1.2 2010/07/18 22:30:55 pooka Exp $ */
+/* $NetBSD: t_sem.c,v 1.3 2010/07/19 10:31:46 jmmv Exp $ */
 
 /*
  * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
@@ -86,7 +86,7 @@
 #include <sys/cdefs.h>
 __COPYRIGHT("@(#) Copyright (c) 2008, 2010\
  The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_sem.c,v 1.2 2010/07/18 22:30:55 pooka Exp $");
+__RCSID("$NetBSD: t_sem.c,v 1.3 2010/07/19 10:31:46 jmmv Exp $");
 
 #include <errno.h>
 #include <fcntl.h>
@@ -99,6 +99,7 @@
 #include <unistd.h>
 
 #include <atf-c.h>
+#include <atf-c/config.h>
 
 #include "h_common.h"
 
@@ -215,60 +216,97 @@
 	SEM_REQUIRE(sem_post(&sem));
 }
 
+static void
+alarm_ms(const int ms)
+{
+	struct itimerval timer;
+	timer.it_interval.tv_sec = 0;
+	timer.it_interval.tv_usec = 0;
+	timer.it_value.tv_sec = 0;
+	timer.it_value.tv_usec = ms * 1000;
+	ATF_REQUIRE(setitimer(ITIMER_REAL, &timer, NULL) == 0);
+}
+
 static void *
 threadfunc(void *arg)
 {
 	int i;
 
+	printf("Entering loop\n");
 	for (i = 0; i < 10; ) {
-		int ret;
-
-		if ((i & 1) != 0)
-			ret = sem_wait(&sem);
-		else
-			ret = sem_trywait(&sem);
-
-		if (ret) {
-			ATF_REQUIRE_MSG((i & 1) == 0 && errno == EAGAIN,
-				"%s", strerror(errno));
-			continue;
+		if ((i & 1) != 0) {
+			ATF_REQUIRE(sem_wait(&sem) != -1);
+		} else {
+			const int ret = sem_trywait(&sem);
+			if (ret == -1) {
+				ATF_REQUIRE(errno == EAGAIN);
+				continue;
+			}
 		}
-
 		printf("%s: %d\n", __func__, i);
-		alarm(1);
+		alarm_ms(100);
 		i++;
 	}
 
 	return NULL;
 }
 
-ATF_TC(before_start);
-ATF_TC_HEAD(before_start, tc)
-{
-	atf_tc_set_md_var(tc, "descr", "Checks using semaphores before "
-	    "starting pthread");
-	atf_tc_set_md_var(tc, "timeout", "20");
-}
-ATF_TC_BODY(before_start, tc)
+static void
+before_start_test(const bool use_pthread)
 {
 	pthread_t t;
 
-	alarm(1);
-
 	SEM_REQUIRE(sem_init(&sem, 0, 0));
+	ATF_REQUIRE(SIG_ERR != signal(SIGALRM, sighandler));
 
-	PTHREAD_REQUIRE(pthread_create(&t, NULL, threadfunc, NULL));
+	alarm_ms(100);
 
-	ATF_REQUIRE(SIG_ERR != signal(SIGALRM, sighandler));
+	if (use_pthread) {
+		PTHREAD_REQUIRE(pthread_create(&t, NULL, threadfunc, NULL));
+		PTHREAD_REQUIRE(pthread_join(t, NULL));
+	} else {
+		threadfunc(NULL);
+	}
+}
+
+ATF_TC(before_start_no_threads);
+ATF_TC_HEAD(before_start_no_threads, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Checks using semaphores without any "
+	    "thread running");
+	atf_tc_set_md_var(tc, "timeout", "20");
+}
+ATF_TC_BODY(before_start_no_threads, tc)
+{
+	before_start_test(false);
+}
 
-	PTHREAD_REQUIRE(pthread_join(t, NULL));
+ATF_TC(before_start_one_thread);
+ATF_TC_HEAD(before_start_one_thread, tc)
+{
+	atf_tc_set_md_var(tc, "descr", "Checks using semaphores before "
+	    "starting one thread");
+	atf_tc_set_md_var(tc, "timeout", "20");
+}
+ATF_TC_BODY(before_start_one_thread, tc)
+{
+	if (strcmp("amd64", atf_config_get("atf_arch")) == 0) {
+		/* TODO(jmmv): This really is a race condition test.  However,
+		 * we cannot yet mark it as such because ATF does not provide
+		 * such functionality.  Let's just mark it as an unconditional
+		 * expected timeout as I haven't got it to pass any single
+		 * time. */
+		atf_tc_expect_timeout("Race condition detected");
+	}
+	before_start_test(true);
 }
 
 ATF_TP_ADD_TCS(tp)
 {
 	ATF_TP_ADD_TC(tp, named);
 	ATF_TP_ADD_TC(tp, unnamed);
-	ATF_TP_ADD_TC(tp, before_start);
+	ATF_TP_ADD_TC(tp, before_start_no_threads);
+	ATF_TP_ADD_TC(tp, before_start_one_thread);
 
 	return atf_no_error();
 }

Reply via email to