libxshmfence: Changes to 'upstream-unstable'
.gitignore | 84 ++++++++++++++++++++++
COPYING | 19 +++++
Makefile.am | 2
README | 36 +++++++++
configure.ac | 146 +++++++++++++++++++++++++++++++++++----
src/Makefile.am | 18 ++++
src/xshmfence.c | 144 --------------------------------------
src/xshmfence.h | 30 ++++----
src/xshmfence_alloc.c | 88 +++++++++++++++++++++++
src/xshmfence_futex.c | 94 +++++++++++++++++++++++++
src/xshmfence_futex.h | 70 ++++++++++++++++++
src/xshmfence_pthread.c | 131 +++++++++++++++++++++++++++++++++++
src/xshmfence_pthread.h | 39 ++++++++++
src/xshmfenceint.h | 44 +----------
test/Makefile.am | 9 ++
test/xshmfence_test.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++
xshmfence.pc.in | 3
17 files changed, 920 insertions(+), 215 deletions(-)
New commits:
commit e8dd66fee206f93e1bee059bdadde064901ed745
Author: Keith Packard <keithp@keithp.com>
Date: Tue Nov 26 21:55:20 2013 -0800
Update to version 1.1
Signed-off-by: Keith Packard <keithp@keithp.com>
diff --git a/configure.ac b/configure.ac
index c592fd6..8a39f22 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@ dnl
dnl Process this file with autoconf to create configure.
AC_PREREQ([2.60])
-AC_INIT([libxshmfence], [1.0],
+AC_INIT([libxshmfence], [1.1],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libxshmfence])
AC_CONFIG_SRCDIR([Makefile.am])
AC_CONFIG_HEADERS([config.h])
commit 4b7c89d0dcaf48140c190dfe6a4560960229ab44
Author: Keith Packard <keithp@keithp.com>
Date: Mon Nov 25 13:36:54 2013 -0800
Describe the library better in the README file
Signed-off-by: Keith Packard <keithp@keithp.com>
diff --git a/README b/README
index 66b36f0..db193b7 100644
--- a/README
+++ b/README
@@ -1,4 +1,15 @@
-libxshmfence - Direct Rendering Infrastructure 3 Extension
+libxshmfence - Shared memory 'SyncFence' synchronization primitive
+
+This library offers a CPU-based synchronization primitive compatible
+with the X SyncFence objects that can be shared between processes
+using file descriptor passing.
+
+There are two underlying implementations:
+
+ 1) On Linux, the library uses futexes
+
+ 2) On other systems, the library uses posix mutexes and condition
+ variables.
All questions regarding this software should be directed at the
Xorg mailing list:
commit c43c79c34d26277609fa02aedc1b862f4a280808
Author: Keith Packard <keithp@keithp.com>
Date: Wed Nov 20 14:21:35 2013 -0800
Ignore test build files and release announcements
Signed-off-by: Keith Packard <keithp@keithp.com>
diff --git a/.gitignore b/.gitignore
index 7414fb0..7cc3af8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,3 +76,9 @@ core
# Edit the following section as needed
# For example, !report.pc overrides *.pc. See 'man gitignore'
#
+libxshmfence-*.announce
+test-driver
+test/test-suite.log
+test/xshmfence_test
+test/xshmfence_test.log
+test/xshmfence_test.trs
commit d4938bf5e57375b70c73831402fc8637996aad31
Author: Keith Packard <keithp@keithp.com>
Date: Wed Nov 20 11:23:56 2013 -0800
Set symbol visibility attribute to hide internal symbols
Expose only the official API.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
diff --git a/configure.ac b/configure.ac
index eab0836..c592fd6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,49 @@ AC_SUBST([PTHREAD_LIBS])
AM_CONDITIONAL([FUTEX], [test x"$FUTEX" = xyes])
AM_CONDITIONAL([PTHREAD], [test x"$PTHREAD" = xyes])
+PKG_CHECK_MODULES(XPROTO, xproto)
+
+AC_SUBST([XPROTO_CFLAGS])
+
+CFLAGS="$CFLAGS $XPROTO_CFLAGS"
+
+AC_ARG_ENABLE(visibility, AC_HELP_STRING([--enable-visibility], [Enable symbol visibility (default: auto)]),
+ [SYMBOL_VISIBILITY=$enableval],
+ [SYMBOL_VISIBILITY=auto])
+
+dnl ==================================================================
+dnl symbol visibility
+symbol_visibility=
+have_visibility=disabled
+if test x$SYMBOL_VISIBILITY != xno; then
+ AC_MSG_CHECKING(for symbol visibility support)
+ if test x$GCC = xyes; then
+ VISIBILITY_CFLAGS="-fvisibility=hidden"
+ else
+ if test x$SUNCC = xyes; then
+ VISIBILITY_CFLAGS="-xldscope=hidden"
+ else
+ have_visibility=no
+ fi
+ fi
+ if test x$have_visibility != xno; then
+ AC_TRY_COMPILE(
+ [#include <X11/Xfuncproto.h>
+ extern _X_HIDDEN int hidden_int;
+ extern _X_EXPORT int public_int;
+ extern _X_HIDDEN int hidden_int_func(void);
+ extern _X_EXPORT int public_int_func(void);],
+ [],
+ have_visibility=yes,
+ have_visibility=no)
+ fi
+ AC_MSG_RESULT([$have_visibility])
+ if test x$have_visibility != xno; then
+ symbol_visibility=$VISIBILITY_CFLAGS
+ CFLAGS="$CFLAGS $VISIBILITY_CFLAGS"
+ fi
+fi
+
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/xshmfence.h b/src/xshmfence.h
index bbdbb53..27d1b82 100644
--- a/src/xshmfence.h
+++ b/src/xshmfence.h
@@ -23,29 +23,31 @@
#ifndef _XSHMFENCE_H_
#define _XSHMFENCE_H_
+#include <X11/Xfuncproto.h>
+
#define HAVE_STRUCT_XSHMFENCE 1
struct xshmfence;
-int
+_X_EXPORT int
xshmfence_trigger(struct xshmfence *f);
-int
+_X_EXPORT int
xshmfence_await(struct xshmfence *f);
-int
+_X_EXPORT int
xshmfence_query(struct xshmfence *f);
-void
+_X_EXPORT void
xshmfence_reset(struct xshmfence *f);
-int
+_X_EXPORT int
xshmfence_alloc_shm(void);
-struct xshmfence *
+_X_EXPORT struct xshmfence *
xshmfence_map_shm(int fd);
-void
+_X_EXPORT void
xshmfence_unmap_shm(struct xshmfence *f);
#endif /* _XSHMFENCE_H_ */
diff --git a/xshmfence.pc.in b/xshmfence.pc.in
index 579af0b..a139fab 100644
--- a/xshmfence.pc.in
+++ b/xshmfence.pc.in
@@ -6,6 +6,6 @@ includedir=@includedir@
Name: xshmfence
Description: The X Shared Memory Fence Library
Version: @PACKAGE_VERSION@
-Cflags: -I${includedir}
+Cflags: -I${includedir} @XPROTO_CFLAGS@
Libs: -L${libdir} -lxshmfence
Libs.private: @PTHREAD_LIBS@
commit e390e3aaee3dace2a1e6cfe66efd884fc256b0f0
Author: Keith Packard <keithp@keithp.com>
Date: Wed Nov 20 11:22:04 2013 -0800
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>
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@
commit daa78ee9a5f9b5590d540aa06466d6728fb2c795
Author: Keith Packard <keithp@keithp.com>
Date: Wed Nov 20 11:19:50 2013 -0800
Split out futex implementation from general API
This splits the futex-specific code out into a separate file so that
future versions of the library could use some other underlying primitive.
Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Adam Jackson <ajax@redhat.com>
diff --git a/src/Makefile.am b/src/Makefile.am
index 70b77a6..0edf904 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,8 +1,11 @@
lib_LTLIBRARIES = libxshmfence.la
+FUTEX_SOURCES=xshmfence_futex.c xshmfence_futex.h
+
libxshmfence_la_SOURCES = \
- xshmfence.c \
- xshmfenceint.h
+ xshmfenceint.h \
+ xshmfence_alloc.c \
+ $(FUTEX_SOURCES)
AM_CFLAGS = $(CWARNFLAGS)
diff --git a/src/xshmfence.c b/src/xshmfence.c
deleted file mode 100644
index ed2b4c4..0000000
--- a/src/xshmfence.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * 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"
-
-struct xshmfence {
- int32_t v;
-};
-
-/**
- * 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)
-{
- if (__sync_val_compare_and_swap(&f->v, 0, 1) == -1) {
- atomic_store(&f->v, 1);
- if (futex_wake(&f->v) < 0)
- return -1;
- }
- 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)
-{
- while (__sync_val_compare_and_swap(&f->v, 0, -1) != 1) {
- if (futex_wait(&f->v, -1)) {
- if (errno != EWOULDBLOCK)
- return -1;
- }
- }
- return 0;
-}
-
-/**
- * xshmfence_query:
- * @f: An X fence
- *
- * Return value: 1 if @f is triggered, else returns 0.
- **/
-int
-xshmfence_query(struct xshmfence *f)
-{
- return atomic_fetch(&f->v) == 1;
-}
-
-/**
- * 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)
-{
- __sync_bool_compare_and_swap(&f->v, 1, 0);
-}
-
-/**
- * xshmfence_alloc_shm:
- *
- * Allocates a shared memory object large enough to hold a single
- * fence.
- *
- * Return value: the file descriptor of the object, or -1 on failure
- * (in which case, errno will be set as appropriate).
- **/
-int
-xshmfence_alloc_shm(void)
-{
- char template[] = SHMDIR "/shmfd-XXXXXX";
- int fd;
-
-#ifdef O_TMPFILE
- fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666);
- if (fd < 0)
-#endif
- {
- fd = mkstemp(template);
- if (fd < 0)
- return fd;
- unlink(template);
- }
- ftruncate(fd, sizeof (struct xshmfence));
- return fd;
-}
-
-/**
- * xshmfence_map_shm:
- *
- * Map a shared memory fence referenced by @fd.
- *
- * Return value: the fence or NULL (in which case, errno will be set
- * as appropriate).
- **/
-struct xshmfence *
-xshmfence_map_shm(int fd)
-{
- struct xshmfence *addr;
- addr = mmap (NULL, sizeof (struct xshmfence) , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (addr == MAP_FAILED) {
- close (fd);
- return 0;
- }
- return addr;
-}
-
-/**
- * xshmfence_unmap_shm:
- *
- * Unap a shared memory fence @f.
- **/
-void
-xshmfence_unmap_shm(struct xshmfence *f)
-{
- munmap(f, sizeof (struct xshmfence));
-}
diff --git a/src/xshmfence_alloc.c b/src/xshmfence_alloc.c
new file mode 100644
index 0000000..d8d4a40
--- /dev/null
+++ b/src/xshmfence_alloc.c
@@ -0,0 +1,88 @@
+/*
+ * 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_alloc_shm:
+ *
+ * Allocates a shared memory object large enough to hold a single
+ * fence.
+ *
+ * Return value: the file descriptor of the object, or -1 on failure
+ * (in which case, errno will be set as appropriate).
+ **/
+int
+xshmfence_alloc_shm(void)
+{
+ char template[] = SHMDIR "/shmfd-XXXXXX";
+ int fd;
+
+#ifdef O_TMPFILE
+ fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666);
+ if (fd < 0)
+#endif
+ {
+ fd = mkstemp(template);
+ if (fd < 0)
+ return fd;
+ unlink(template);
+ }
+ ftruncate(fd, sizeof (struct xshmfence));
+ xshmfence_init(fd);
+ return fd;
+}
+
+/**
+ * xshmfence_map_shm:
+ *
+ * Map a shared memory fence referenced by @fd.
+ *
+ * Return value: the fence or NULL (in which case, errno will be set
+ * as appropriate).
+ **/
+struct xshmfence *
+xshmfence_map_shm(int fd)
+{
+ struct xshmfence *addr;
+ addr = mmap (NULL, sizeof (struct xshmfence) , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ close (fd);
+ return 0;
+ }
+ return addr;
+}
+
+/**
+ * xshmfence_unmap_shm:
+ *
+ * Unap a shared memory fence @f.
+ **/
+void
+xshmfence_unmap_shm(struct xshmfence *f)
+{
+ munmap(f, sizeof (struct xshmfence));
+}
diff --git a/src/xshmfence_futex.c b/src/xshmfence_futex.c
new file mode 100644
index 0000000..8b42491
--- /dev/null
+++ b/src/xshmfence_futex.c
@@ -0,0 +1,94 @@
+/*
+ * 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)
+{
+ if (__sync_val_compare_and_swap(&f->v, 0, 1) == -1) {
+ atomic_store(&f->v, 1);
+ if (futex_wake(&f->v) < 0)
+ return -1;
+ }
+ 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)
+{
+ while (__sync_val_compare_and_swap(&f->v, 0, -1) != 1) {
+ if (futex_wait(&f->v, -1)) {
+ if (errno != EWOULDBLOCK)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * xshmfence_query:
+ * @f: An X fence
+ *
+ * Return value: 1 if @f is triggered, else returns 0.
+ **/
+int
+xshmfence_query(struct xshmfence *f)
+{
+ return atomic_fetch(&f->v) == 1;
+}
+
+/**
+ * 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)
+{
+ __sync_bool_compare_and_swap(&f->v, 1, 0);
+}
diff --git a/src/xshmfence_futex.h b/src/xshmfence_futex.h
new file mode 100644
index 0000000..ed60b6d
--- /dev/null
+++ b/src/xshmfence_futex.h
@@ -0,0 +1,70 @@
+/*
+ * 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_FUTEX_H_
+#define _XSHMFENCE_FUTEX_H_
+
+#include <errno.h>
+#include <stdint.h>
+#include <values.h>
+#include <linux/futex.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+static inline long sys_futex(void *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3)
+{
+ return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
+}
+
+static inline int futex_wake(int32_t *addr) {
+ return sys_futex(addr, FUTEX_WAKE, MAXINT, NULL, NULL, 0);
+}
+
+static inline int futex_wait(int32_t *addr, int32_t value) {
+ return sys_futex(addr, FUTEX_WAIT, value, NULL, NULL, 0);
+}
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+static inline void atomic_store(int32_t *f, int32_t v)
+{
+ barrier();
+ *f = v;
+ barrier();
+}
+
+static inline int32_t atomic_fetch(int32_t *a)
+{
+ int32_t v;
+ barrier();
+ v = *a;
+ barrier();
+ return v;
+}
+
+struct xshmfence {
+ int32_t v;
+};
+
+#define xshmfence_init(fd)
+
+#endif /* _XSHMFENCE_FUTEX_H_ */
diff --git a/src/xshmfenceint.h b/src/xshmfenceint.h
index 66862d0..3452a55 100644
--- a/src/xshmfenceint.h
+++ b/src/xshmfenceint.h
@@ -23,50 +23,10 @@
#ifndef _XSHMFENCEINT_H_
#define _XSHMFENCEINT_H_
-#include <stdint.h>
-#include <stdio.h>
-#include <stddef.h>
#include <stdlib.h>
-#include <linux/futex.h>
-#include <sys/time.h>
#include <unistd.h>
-#include <sys/syscall.h>
#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <values.h>
#include "xshmfence.h"
+#include "xshmfence_futex.h"
Reply to: