Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/tests/lib Add tests for semaphores. Note: the "unlink" one ...
details: https://anonhg.NetBSD.org/src/rev/51925a187ff3
branches: trunk
changeset: 755595:51925a187ff3
user: pooka <pooka%NetBSD.org@localhost>
date: Thu Jun 10 22:03:43 2010 +0000
description:
Add tests for semaphores. Note: the "unlink" one fails because our
implementation is broken. I'll file a PR shortly.
diffstat:
tests/lib/Makefile | 4 +-
tests/lib/semaphore/Atffile | 6 +
tests/lib/semaphore/Makefile | 9 +
tests/lib/semaphore/pthread/Atffile | 6 +
tests/lib/semaphore/pthread/Makefile | 15 +
tests/lib/semaphore/pthread/t_sem_pth.c | 16 +
tests/lib/semaphore/sem.c | 299 ++++++++++++++++++++++++++++++++
7 files changed, 353 insertions(+), 2 deletions(-)
diffs (truncated from 389 to 300 lines):
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/Makefile
--- a/tests/lib/Makefile Thu Jun 10 22:00:02 2010 +0000
+++ b/tests/lib/Makefile Thu Jun 10 22:03:43 2010 +0000
@@ -1,8 +1,8 @@
-# $NetBSD: Makefile,v 1.2 2009/11/02 10:15:45 plunky Exp $
+# $NetBSD: Makefile,v 1.3 2010/06/10 22:03:43 pooka Exp $
.include <bsd.own.mk>
-SUBDIR= libc libevent
+SUBDIR= libc libevent semaphore
TESTSDIR= ${TESTSBASE}/lib
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/Atffile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/Atffile Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,6 @@
+Content-Type: application/X-atf-atffile; version="1"
+X-NetBSD-Id: "$NetBSD: Atffile,v 1.1 2010/06/10 22:03:43 pooka Exp $"
+
+prop: test-suite = "NetBSD"
+
+tp: pthread
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/Makefile Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,9 @@
+# $NetBSD: Makefile,v 1.1 2010/06/10 22:03:43 pooka Exp $
+#
+
+SUBDIR= pthread
+
+TESTSDIR= ${TESTSBASE}/lib/semaphore
+
+.include <bsd.test.mk>
+.include <bsd.subdir.mk>
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/pthread/Atffile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/pthread/Atffile Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,6 @@
+Content-Type: application/X-atf-atffile; version="1"
+X-NetBSD-Id: "$NetBSD: Atffile,v 1.1 2010/06/10 22:03:43 pooka Exp $"
+
+prop: test-suite = "NetBSD"
+
+tp-glob: t_*
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/pthread/Makefile
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/pthread/Makefile Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,15 @@
+# $NetBSD: Makefile,v 1.1 2010/06/10 22:03:43 pooka Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/lib/semaphore/pthread
+
+TESTS_C= t_sem_pth
+
+CPPFLAGS+= -I${.CURDIR}/..
+
+LDADD+= -lrumpkern_ksem -lrump -lrumpuser -lpthread
+
+WARNS= 4
+
+.include <bsd.test.mk>
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/pthread/t_sem_pth.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/pthread/t_sem_pth.c Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,16 @@
+#define LIBNAME "pthread"
+#include "sem.c"
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, postwait);
+ ATF_TP_ADD_TC(tp, initvalue);
+ ATF_TP_ADD_TC(tp, destroy);
+ ATF_TP_ADD_TC(tp, busydestroy);
+ ATF_TP_ADD_TC(tp, blockwait);
+ ATF_TP_ADD_TC(tp, named);
+ ATF_TP_ADD_TC(tp, unlink);
+
+ return atf_no_error();
+}
diff -r 198b7d9185c0 -r 51925a187ff3 tests/lib/semaphore/sem.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/lib/semaphore/sem.c Thu Jun 10 22:03:43 2010 +0000
@@ -0,0 +1,299 @@
+/* $NetBSD: sem.c,v 1.1 2010/06/10 22:03:43 pooka Exp $ */
+
+/*
+ * Common code for semaphore tests. This can be included both into
+ * programs using librt and libpthread.
+ */
+
+#include <sys/types.h>
+
+#include <rump/rump.h>
+#include <rump/rump_syscalls.h>
+
+#include <atf-c.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <sched.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "../../h_macros.h"
+
+ATF_TC(postwait);
+ATF_TC_HEAD(postwait, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests post and wait from a "
+ "single thread (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(postwait, tc)
+{
+ sem_t sem;
+ int rv;
+
+ rump_init();
+
+ ATF_REQUIRE_EQ(sem_init(&sem, 1, 0), 0);
+
+ sem_post(&sem);
+ sem_post(&sem);
+
+ sem_wait(&sem);
+ sem_wait(&sem);
+ rv = sem_trywait(&sem);
+ ATF_REQUIRE(errno == EAGAIN);
+ ATF_REQUIRE(rv == -1);
+}
+
+ATF_TC(initvalue);
+ATF_TC_HEAD(initvalue, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests initialization with a non-zero "
+ "value (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(initvalue, tc)
+{
+ sem_t sem;
+
+ rump_init();
+ sem_init(&sem, 1, 4);
+
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), -1);
+}
+
+ATF_TC(destroy);
+ATF_TC_HEAD(destroy, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests sem_destroy works (%s)", LIBNAME);
+}
+
+ATF_TC_BODY(destroy, tc)
+{
+ sem_t sem;
+ int rv, i;
+
+ rump_init();
+ for (i = 0; i < 2; i++) {
+ sem_init(&sem, 1, 1);
+
+ ATF_REQUIRE_EQ(sem_trywait(&sem), 0);
+ ATF_REQUIRE_EQ(sem_trywait(&sem), -1);
+ ATF_REQUIRE_EQ(sem_destroy(&sem), 0);
+ rv = sem_trywait(&sem);
+ ATF_REQUIRE_EQ(errno, EINVAL);
+ ATF_REQUIRE_EQ(rv, -1);
+ }
+}
+
+ATF_TC(busydestroy);
+ATF_TC_HEAD(busydestroy, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests sem_destroy report EBUSY for "
+ "a busy semaphore (%s)", LIBNAME);
+}
+
+static void *
+hthread(void *arg)
+{
+ sem_t *semmarit = arg;
+
+ for (;;) {
+ sem_post(&semmarit[2]);
+ sem_wait(&semmarit[1]);
+ sem_wait(&semmarit[0]);
+ }
+}
+
+ATF_TC_BODY(busydestroy, tc)
+{
+ sem_t semmarit[3];
+ pthread_t pt;
+ int i;
+
+ /* use a unicpu rump kernel. this means less chance for race */
+ setenv("RUMP_NCPU", "1", 1);
+
+ rump_init();
+ sem_init(&semmarit[0], 1, 0);
+ sem_init(&semmarit[1], 1, 0);
+ sem_init(&semmarit[2], 1, 0);
+
+ pthread_create(&pt, NULL, hthread, semmarit);
+
+ /*
+ * Make a best-effort to catch the other thread with its pants down.
+ * We can't do this for sure, can we? Although, we could reach
+ * inside the rump kernel and inquire about the thread's sleep
+ * status.
+ */
+ for (i = 0; i < 1000; i++) {
+ sem_wait(&semmarit[2]);
+ usleep(1);
+ if (sem_destroy(&semmarit[1]) == -1)
+ if (errno == EBUSY)
+ break;
+
+ /*
+ * Didn't catch it? ok, recreate and post to make the
+ * other thread run
+ */
+ sem_init(&semmarit[1], 1, 0);
+ sem_post(&semmarit[0]);
+ sem_post(&semmarit[1]);
+
+ }
+ if (i == 1000)
+ atf_tc_fail("sem destroy not reporting EBUSY");
+}
+
+ATF_TC(blockwait);
+ATF_TC_HEAD(blockwait, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests sem_wait can handle blocking "
+ "(%s)", LIBNAME);
+}
+
+ATF_TC_BODY(blockwait, tc)
+{
+ sem_t semmarit[3];
+ pthread_t pt;
+ int i;
+
+ rump_init();
+ sem_init(&semmarit[0], 1, 0);
+ sem_init(&semmarit[1], 1, 0);
+ sem_init(&semmarit[2], 1, 0);
+
+ pthread_create(&pt, NULL, hthread, semmarit);
+
+ /*
+ * Make a best-effort. Unless we're extremely unlucky, we should
+ * at least one blocking wait.
+ */
+ for (i = 0; i < 10; i++) {
+ sem_wait(&semmarit[2]);
+ usleep(1);
+ sem_post(&semmarit[0]);
+ sem_post(&semmarit[1]);
+
+ }
+ if (i == 1000)
+ atf_tc_fail("sem destroy not reporting EBUSY");
+}
+
+ATF_TC(named);
+ATF_TC_HEAD(named, tc)
+{
+
+ atf_tc_set_md_var(tc, "descr", "tests named semaphores (%s)", LIBNAME);
+}
+
+/*
+ * Wow, easy naming rules. it's these times i'm really happy i can
+ * single-step into the kernel.
+ */
+#define SEM1 "/my_precious_sem"
+#define SEM2 "/justsem"
Home |
Main Index |
Thread Index |
Old Index