[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: