summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-11-20 09:13:48 -0800
committerKeith Packard <keithp@keithp.com>2013-11-20 14:13:08 -0800
commite15fa576597fb09330e603d17a51d7449a392e7c (patch)
tree642ada047b9ae5c81c2f38c79902b06801f8f20b
parentbdbb26378da91e541f2fe2b3e827d9f6ed11f4a8 (diff)
Add test program
Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r--Makefile.am2
-rw-r--r--configure.ac1
-rw-r--r--test/Makefile.am9
-rw-r--r--test/xshmfence_test.c178
4 files changed, 189 insertions, 1 deletions
diff --git a/Makefile.am b/Makefile.am
index 92503b3..670cdcb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -20,7 +20,7 @@
# OF THIS SOFTWARE.
#
-SUBDIRS = src
+SUBDIRS = src test
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = xshmfence.pc
diff --git a/configure.ac b/configure.ac
index 58b3583..3493dd2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -91,5 +91,6 @@ esac
AC_CONFIG_FILES([Makefile
src/Makefile
+ test/Makefile
xshmfence.pc])
AC_OUTPUT
diff --git a/test/Makefile.am b/test/Makefile.am
new file mode 100644
index 0000000..c67014a
--- /dev/null
+++ b/test/Makefile.am
@@ -0,0 +1,9 @@
+check_PROGRAMS = xshmfence_test
+
+TESTS=$(check_PROGRAMS)
+
+xshmfence_test_SOURCES = xshmfence_test.c
+
+xshmfence_test_CFLAGS = -I$(top_srcdir)/src
+xshmfence_test_LDADD = $(top_builddir)/src/libxshmfence.la
+
diff --git a/test/xshmfence_test.c b/test/xshmfence_test.c
new file mode 100644
index 0000000..43ecf2e
--- /dev/null
+++ b/test/xshmfence_test.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <xshmfence.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#define NCHILD 5 /* number of child processes to fork */
+#define NCHECK 10 /* number of times to signal the fence */
+
+/* Catch an alarm and bail
+ */
+static void
+sigalrm(int sig)
+{
+ write(2, "caught alarm\n", 13);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ int fd;
+ struct xshmfence *x;
+ int i;
+ int c;
+ int pid;
+ int status;
+ int failed = 0;
+
+ /* Allocate a fence
+ */
+ fd = xshmfence_alloc_shm();
+ if (fd < 0) {
+ perror("xshmfence_alloc_shm");
+ exit(1);
+ }
+
+ /* fork NCHILD processes to wait for the fence
+ */
+ for (c = 0; c < NCHILD; c++) {
+ switch (fork()) {
+ case -1:
+ perror("fork");
+ exit(1);
+ case 0:
+
+ /* Set an alarm to limit how long
+ * to wait
+ */
+ signal(SIGALRM, sigalrm);
+ alarm(10);
+
+ /* Map the fence
+ */
+ x = xshmfence_map_shm(fd);
+ if (!x) {
+ fprintf(stderr, "%6d: ", c);
+ perror("xshmfence_map_shm");
+ exit(1);
+ }
+
+ for (i = 0; i < NCHECK; i++) {
+
+ /* Verify that the fence is currently reset
+ */
+ if (xshmfence_query(x) != 0) {
+ fprintf(stderr, "%6d: query reset failed\n", c);
+ exit(1);
+ }
+
+ /* Wait for the fence
+ */
+ fprintf(stderr, "%6d: waiting\n", c);
+ if (xshmfence_await(x) < 0) {
+ fprintf(stderr, "%6d: ", c);
+ perror("xshmfence_await");
+ exit(1);
+ }
+
+ fprintf(stderr, "%6d: awoken\n", c);
+
+ /* Verify that the fence is currently triggered
+ */
+ if (xshmfence_query(x) == 0) {
+ fprintf(stderr, "%6d: query triggered failed\n", c);
+ exit(1);
+ }
+
+ usleep(10 * 1000);
+
+ /* Reset the fence
+ */
+ if (c == 0)
+ xshmfence_reset(x);
+
+ usleep(10 * 1000);
+ }
+ fprintf(stderr, "%6d: done\n", c);
+ exit(0);
+ }
+ }
+
+ /* Map the fence into the parent process
+ */
+ x = xshmfence_map_shm(fd);
+ if (!x) {
+ perror("xshmfence_map_shm");
+ exit(1);
+ }
+
+ for (i = 0; i < NCHECK; i++) {
+ usleep(100 * 1000);
+ fprintf(stderr, "trigger\n");
+
+ /* Verify that the fence is reset
+ */
+ if (xshmfence_query(x) != 0) {
+ fprintf(stderr, "query reset failed\n");
+ exit(1);
+ }
+
+ /* Trigger the fence
+ */
+ if (xshmfence_trigger(x) < 0) {
+ perror("xshmfence_trigger");
+ exit(1);
+ }
+
+ /* Verify that the fence is triggered
+ */
+ if (xshmfence_query(x) == 0) {
+ fprintf (stderr, "query triggered failed\n");
+ exit(1);
+ }
+
+ fprintf(stderr, "trigger done\n");
+ }
+
+ /* Reap all of the child processes
+ */
+ for (c = 0; c < NCHILD; c++) {
+ pid = wait(&status);
+ if (pid < 0) {
+ perror("wait");
+ exit(1);
+ }
+ fprintf(stderr, "child %d done %d\n", pid, status);
+ if (status)
+ failed++;
+ }
+ exit(failed);
+}