[PATCH 4/7] Add test program
Keith Packard
keithp at keithp.com
Wed Nov 20 11:55:58 PST 2013
Signed-off-by: Keith Packard <keithp at keithp.com>
---
Makefile.am | 2 +-
configure.ac | 1 +
test/Makefile.am | 9 +++
test/xshmfence_test.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 189 insertions(+), 1 deletion(-)
create mode 100644 test/Makefile.am
create mode 100644 test/xshmfence_test.c
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 02359e1..ee09faf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,4 +90,5 @@ XORG_CHANGELOG
AC_OUTPUT([Makefile
src/Makefile
+ test/Makefile
xshmfence.pc])
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);
+}
--
1.8.4.2
More information about the xorg-devel
mailing list