diff options
author | Keith Packard <keithp@keithp.com> | 2013-11-20 09:13:48 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-11-20 14:13:08 -0800 |
commit | e15fa576597fb09330e603d17a51d7449a392e7c (patch) | |
tree | 642ada047b9ae5c81c2f38c79902b06801f8f20b | |
parent | bdbb26378da91e541f2fe2b3e827d9f6ed11f4a8 (diff) |
Add test program
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | test/Makefile.am | 9 | ||||
-rw-r--r-- | test/xshmfence_test.c | 178 |
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); +} |