diff options
author | Keith Packard <keithp@keithp.com> | 2013-11-20 11:22:04 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2013-11-20 14:14:58 -0800 |
commit | e390e3aaee3dace2a1e6cfe66efd884fc256b0f0 (patch) | |
tree | c9445900402899bca8e6beb6e6d2560d77954629 | |
parent | daa78ee9a5f9b5590d540aa06466d6728fb2c795 (diff) |
Provide pthread-based alternative implementation
This uses pthread mutexes and condition variables instead of futexes.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
-rw-r--r-- | configure.ac | 25 | ||||
-rw-r--r-- | src/Makefile.am | 8 | ||||
-rw-r--r-- | src/xshmfence_pthread.c | 131 | ||||
-rw-r--r-- | src/xshmfence_pthread.h | 39 | ||||
-rw-r--r-- | src/xshmfenceint.h | 7 | ||||
-rw-r--r-- | test/Makefile.am | 2 | ||||
-rw-r--r-- | xshmfence.pc.in | 1 |
7 files changed, 212 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac index 3493dd2..eab0836 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,31 @@ dnl dnl Locate a suitable tmp file system for creating shared memeory files dnl +AC_ARG_ENABLE(futex, AS_HELP_STRING([--enable-futex], [Enable futexes (default: auto)]), + [FUTEX=$enableval], [FUTEX=auto]) + +if test "x$FUTEX" = "xauto"; then + AC_CHECK_HEADER([linux/futex.h], [FUTEX=yes], [FUTEX=no]) +fi + +if test "x$FUTEX" = "xyes"; then + PTHREAD=no + AC_DEFINE(HAVE_FUTEX,1,[Use futexes]) +else + PTHREAD=yes + AC_DEFINE(HAVE_PTHREAD,1,[Use pthread primitives]) +fi + +PTHREAD_LIBS= +if test "x$PTHREAD" = "xyes"; then + AC_CHECK_LIB(pthread,pthread_create,[PTHREAD_LIBS=-lpthread],[PTHREAD_LIBS=]) +fi + +AC_SUBST([PTHREAD_LIBS]) + +AM_CONDITIONAL([FUTEX], [test x"$FUTEX" = xyes]) +AM_CONDITIONAL([PTHREAD], [test x"$PTHREAD" = xyes]) + AC_ARG_WITH(shared-memory-dir, AS_HELP_STRING([--with-shared-memory-dir=PATH], [Path to directory in a world-writable temporary directory for anonymous shared memory (default: auto)]), [], [with_shared_memory_dir=yes]) diff --git a/src/Makefile.am b/src/Makefile.am index 0edf904..1a67bdd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,15 +1,23 @@ lib_LTLIBRARIES = libxshmfence.la +if PTHREAD +PTHREAD_SOURCES=xshmfence_pthread.c xshmfence_pthread.h +endif + +if FUTEX FUTEX_SOURCES=xshmfence_futex.c xshmfence_futex.h +endif libxshmfence_la_SOURCES = \ xshmfenceint.h \ xshmfence_alloc.c \ + $(PTHREAD_SOURCES) \ $(FUTEX_SOURCES) AM_CFLAGS = $(CWARNFLAGS) libxshmfence_la_LDFLAGS = -version-number 1:0:0 -no-undefined +libxshmfence_la_LIBADD = @PTHREAD_LIBS@ libxshmfenceincludedir = $(includedir)/X11 libxshmfenceinclude_HEADERS = xshmfence.h diff --git a/src/xshmfence_pthread.c b/src/xshmfence_pthread.c new file mode 100644 index 0000000..efa5027 --- /dev/null +++ b/src/xshmfence_pthread.c @@ -0,0 +1,131 @@ +/* + * 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. + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xshmfenceint.h" + +/** + * xshmfence_trigger: + * @f: An X fence + * + * Set @f to triggered, waking all waiters. + * + * Return value: 0 on success and -1 on error (in which case, errno + * will be set as appropriate). + **/ +int +xshmfence_trigger(struct xshmfence *f) { + pthread_mutex_lock(&f->lock); + if (f->value == 0) { + f->value = 1; + if (f->waiting) { + f->waiting = 0; + pthread_cond_broadcast(&f->wakeup); + } + } + pthread_mutex_unlock(&f->lock); + return 0; +} + +/** + * xshmfence_await: + * @f: An X fence + * + * Wait for @f to be triggered. If @f is already triggered, this + * function returns immediately. + * + * Return value: 0 on success and -1 on error (in which case, errno + * will be set as appropriate). + **/ +int +xshmfence_await(struct xshmfence *f) { + pthread_mutex_lock(&f->lock); + while (f->value == 0) { + f->waiting = 1; + pthread_cond_wait(&f->wakeup, &f->lock); + } + pthread_mutex_unlock(&f->lock); + return 0; +} + +/** + * xshmfence_query: + * @f: An X fence + * + * Return value: 1 if @f is triggered, else returns 0. + **/ +int +xshmfence_query(struct xshmfence *f) { + int value; + + pthread_mutex_lock(&f->lock); + value = f->value; + pthread_mutex_unlock(&f->lock); + return value; +} + +/** + * xshmfence_reset: + * @f: An X fence + * + * Reset @f to untriggered. If @f is already untriggered, + * this function has no effect. + **/ +void +xshmfence_reset(struct xshmfence *f) { + + pthread_mutex_lock(&f->lock); + f->value = 0; + pthread_mutex_unlock(&f->lock); +} + +/** + * xshmfence_init: + * @fd: An fd for an X fence + * + * Initialize the fence when first allocated + **/ + +void +xshmfence_init(int fd) +{ + struct xshmfence *f = xshmfence_map_shm(fd); + pthread_mutexattr_t mutex_attr; + pthread_condattr_t cond_attr; + + if (!f) + return; + + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED); + pthread_mutex_init(&f->lock, &mutex_attr); + + pthread_condattr_init(&cond_attr); + pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED); + pthread_cond_init(&f->wakeup, &cond_attr); + f->value = 0; + f->waiting = 0; + xshmfence_unmap_shm(f); +} diff --git a/src/xshmfence_pthread.h b/src/xshmfence_pthread.h new file mode 100644 index 0000000..9d6b0c8 --- /dev/null +++ b/src/xshmfence_pthread.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#ifndef _XSHMFENCE_PTHREAD_H_ +#define _XSHMFENCE_PTHREAD_H_ + +#include <pthread.h> +#include <sys/types.h> + +struct xshmfence { + pthread_mutex_t lock; + pthread_cond_t wakeup; + int value; + int waiting; +}; + +void +xshmfence_init(int fd); + +#endif /* _XSHMFENCE_PTHREAD_H_ */ diff --git a/src/xshmfenceint.h b/src/xshmfenceint.h index 3452a55..178cbdd 100644 --- a/src/xshmfenceint.h +++ b/src/xshmfenceint.h @@ -27,6 +27,13 @@ #include <unistd.h> #include <sys/mman.h> #include "xshmfence.h" + +#if HAVE_FUTEX #include "xshmfence_futex.h" +#endif + +#if HAVE_PTHREAD +#include "xshmfence_pthread.h" +#endif #endif /* _XSHMFENCEINT_H_ */ diff --git a/test/Makefile.am b/test/Makefile.am index c67014a..57bf1ae 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -5,5 +5,5 @@ TESTS=$(check_PROGRAMS) xshmfence_test_SOURCES = xshmfence_test.c xshmfence_test_CFLAGS = -I$(top_srcdir)/src -xshmfence_test_LDADD = $(top_builddir)/src/libxshmfence.la +xshmfence_test_LDADD = $(top_builddir)/src/libxshmfence.la @PTHREAD_LIBS@ diff --git a/xshmfence.pc.in b/xshmfence.pc.in index cfc1860..579af0b 100644 --- a/xshmfence.pc.in +++ b/xshmfence.pc.in @@ -8,3 +8,4 @@ Description: The X Shared Memory Fence Library Version: @PACKAGE_VERSION@ Cflags: -I${includedir} Libs: -L${libdir} -lxshmfence +Libs.private: @PTHREAD_LIBS@ |