summaryrefslogtreecommitdiff
path: root/regress
diff options
context:
space:
mode:
Diffstat (limited to 'regress')
-rw-r--r--regress/lib/libpthread/semaphore/Makefile4
-rw-r--r--regress/lib/libpthread/semaphore/sem_timedwait/Makefile5
-rw-r--r--regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c117
3 files changed, 124 insertions, 2 deletions
diff --git a/regress/lib/libpthread/semaphore/Makefile b/regress/lib/libpthread/semaphore/Makefile
index a9a7dad7b02..6d8b2338af2 100644
--- a/regress/lib/libpthread/semaphore/Makefile
+++ b/regress/lib/libpthread/semaphore/Makefile
@@ -1,5 +1,5 @@
-# $OpenBSD: Makefile,v 1.1 2012/01/04 17:36:40 mpi Exp $
+# $OpenBSD: Makefile,v 1.2 2012/03/03 11:08:12 guenther Exp $
-SUBDIR = sem_destroy sem_getvalue sem_trywait sem_wait
+SUBDIR = sem_destroy sem_getvalue sem_trywait sem_wait sem_timedwait
.include <bsd.subdir.mk>
diff --git a/regress/lib/libpthread/semaphore/sem_timedwait/Makefile b/regress/lib/libpthread/semaphore/sem_timedwait/Makefile
new file mode 100644
index 00000000000..c7168a14afd
--- /dev/null
+++ b/regress/lib/libpthread/semaphore/sem_timedwait/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.1 2012/03/03 11:08:12 guenther Exp $
+
+PROG= sem_timedwait
+
+.include <bsd.regress.mk>
diff --git a/regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c b/regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c
new file mode 100644
index 00000000000..38e0ebe18c7
--- /dev/null
+++ b/regress/lib/libpthread/semaphore/sem_timedwait/sem_timedwait.c
@@ -0,0 +1,117 @@
+/* $OpenBSD: sem_timedwait.c,v 1.1 2012/03/03 11:08:12 guenther Exp $ */
+/*
+ * Martin Pieuchot <mpi@openbsd.org>, 2011. Public Domain.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <unistd.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <pthread.h>
+#include "test.h"
+
+
+void *waiter(void *arg);
+
+void
+handler(int sig)
+{
+ static char message[] = "got sig\n";
+
+ write(STDERR_FILENO, message, sizeof(message) - 1);
+}
+
+sem_t sem;
+volatile int posted = 0, eintr_ok = 0;
+
+int
+main(int argc, char **argv)
+{
+ pthread_t th;
+ struct sigaction sa;
+ struct timespec ts, ts2;
+
+ CHECKr(clock_gettime(CLOCK_REALTIME, &ts));
+ ts.tv_sec += 3;
+ CHECKn(sem_timedwait(&sem, &ts));
+ ASSERT(errno == EINVAL);
+
+ CHECKr(sem_init(&sem, 0, 0));
+
+ CHECKr(pthread_create(&th, NULL, waiter, &sem));
+
+ sleep(1);
+
+ printf("expect: sem_destroy on semaphore with waiters!\n");
+ CHECKn(sem_destroy(&sem));
+ ASSERT(errno == EBUSY);
+
+ posted = 1;
+ CHECKr(sem_post(&sem));
+ CHECKr(pthread_join(th, NULL));
+
+ /* test that sem_timedwait() resumes after handling a signal */
+ memset(&sa, 0, sizeof sa);
+ sa.sa_handler = &handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGUSR1, &sa, NULL))
+ err(1, "sigaction");
+ posted = 0;
+ CHECKr(pthread_create(&th, NULL, waiter, &sem));
+ sleep(1);
+ fprintf(stderr, "sending sig\n");
+ eintr_ok = 1;
+ pthread_kill(th, SIGUSR1);
+ sleep(1);
+ fprintf(stderr, "posting\n");
+ posted = 1;
+ eintr_ok = 0;
+ CHECKr(sem_post(&sem));
+ CHECKr(pthread_join(th, NULL));
+
+ CHECKr(clock_gettime(CLOCK_REALTIME, &ts));
+ ts.tv_sec += 2;
+ CHECKn(sem_timedwait(&sem, &ts));
+ ASSERT(errno == ETIMEDOUT);
+ CHECKr(clock_gettime(CLOCK_REALTIME, &ts2));
+ if (timespeccmp(&ts, &ts2, < ))
+ timespecsub(&ts2, &ts, &ts);
+ else
+ timespecsub(&ts, &ts2, &ts);
+ CHECKr(clock_getres(CLOCK_REALTIME, &ts2));
+ ASSERT(timespeccmp(&ts, &ts2, < ));
+
+ CHECKe(sem_destroy(&sem));
+
+ SUCCEED;
+}
+
+void *
+waiter(void *arg)
+{
+ sem_t *semp = arg;
+ struct timespec ts;
+ int value;
+ int r;
+
+ CHECKr(clock_gettime(CLOCK_REALTIME, &ts));
+ ts.tv_sec += 3;
+ r = sem_timedwait(semp, &ts);
+ CHECKr(sem_getvalue(semp, &value));
+ if (r == 0) {
+ ASSERT(value == 0);
+ ASSERT(posted != 0);
+ } else {
+ ASSERT(r == -1);
+ ASSERT(errno == EINTR);
+ ASSERT(eintr_ok);
+ if (posted)
+ ASSERT(value == 1);
+ else
+ ASSERT(value == 0);
+ }
+
+ return (NULL);
+}