tizen 2.4 release accepted/tizen_2.4_mobile tizen_2.4 accepted/tizen/2.4/mobile/20151029.025950 submit/tizen_2.4/20151028.065321 tizen_2.4_mobile_release
authorjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 07:05:36 +0000 (16:05 +0900)
committerjk7744.park <jk7744.park@samsung.com>
Mon, 26 Oct 2015 07:05:36 +0000 (16:05 +0900)
20 files changed:
COPYING [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
packaging/baselibs.conf [new file with mode: 0644]
packaging/libXshmfence.changes [new file with mode: 0644]
packaging/libXshmfence.manifest [new file with mode: 0644]
packaging/libXshmfence.spec [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/xshmfence.h [new file with mode: 0644]
src/xshmfence_alloc.c [new file with mode: 0644]
src/xshmfence_futex.c [new file with mode: 0644]
src/xshmfence_futex.h [new file with mode: 0644]
src/xshmfence_pthread.c [new file with mode: 0644]
src/xshmfence_pthread.h [new file with mode: 0644]
src/xshmfenceint.h [new file with mode: 0644]
test/Makefile.am [new file with mode: 0644]
test/xshmfence_test.c [new file with mode: 0644]
xshmfence.pc.in [new file with mode: 0644]

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..8dcf1d4
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,19 @@
+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.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..670cdcb
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+SUBDIRS = src test
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = xshmfence.pc
+
+EXTRA_DIST = xshmfence.pc.in ChangeLog
+MAINTAINERCLEANFILES = ChangeLog
+
+.PHONY: ChangeLog
+
+ChangeLog:
+       $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog
+
+if LINT
+lint:
+       (cd src && $(MAKE) $(MFLAGS) lint)
+endif LINT
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..db193b7
--- /dev/null
+++ b/README
@@ -0,0 +1,36 @@
+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:
+
+        http://lists.freedesktop.org/mailman/listinfo/xorg
+
+Please submit bug reports to the Xorg bugzilla:
+
+        https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
+
+The master development code repository can be found at:
+
+        git://anongit.freedesktop.org/git/xorg/lib/libxshmfence
+
+        http://cgit.freedesktop.org/xorg/lib/libxshmfence
+
+For patch submission instructions, see:
+
+       http://www.x.org/wiki/Development/Documentation/SubmittingPatches
+
+For more information on the git code manager, see:
+
+        http://wiki.x.org/wiki/GitPage
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..904cd67
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..8a39f22
--- /dev/null
@@ -0,0 +1,164 @@
+dnl
+dnl Copyright © 2013 Keith Packard
+dnl
+dnl Permission to use, copy, modify, distribute, and sell this software and its
+dnl documentation for any purpose is hereby granted without fee, provided that
+dnl the above copyright notice appear in all copies and that both that copyright
+dnl notice and this permission notice appear in supporting documentation, and
+dnl that the name of the copyright holders not be used in advertising or
+dnl publicity pertaining to distribution of the software without specific,
+dnl written prior permission.  The copyright holders make no representations
+dnl about the suitability of this software for any purpose.  It is provided "as
+dnl is" without express or implied warranty.
+dnl
+dnl THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+dnl INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+dnl EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+dnl CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+dnl DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+dnl TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+dnl OF THIS SOFTWARE.
+dnl
+dnl
+dnl Process this file with autoconf to create configure.
+
+AC_PREREQ([2.60])
+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])
+
+# Initialize Automake
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Initialize libtool
+AC_PROG_LIBTOOL
+
+# Require xorg-macros: XORG_DEFAULT_OPTIONS, XORG_WITH_LINT
+m4_ifndef([XORG_MACROS_VERSION],
+          [m4_fatal([must install xorg-macros 1.3 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.3)
+XORG_DEFAULT_OPTIONS
+
+dnl Allow checking code with lint, sparse, etc.
+XORG_WITH_LINT
+LINT_FLAGS="${LINT_FLAGS} ${FONTENC_CFLAGS}"
+
+                 
+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])
+
+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])
+
+shmdirs="/run/shm /var/tmp /tmp"
+
+case x"$with_shared_memory_dir" in
+xyes)
+       for dir in $shmdirs; do
+               case x"$with_shared_memory_dir" in
+               xyes)
+                       echo Checking temp dir "$dir"
+                       if test -d "$dir"; then
+                               with_shared_memory_dir="$dir"
+                       fi
+                       ;;
+               esac
+       done
+       ;;
+x/*)
+       ;;
+xno)
+       ;;
+*)
+       AC_MSG_ERROR([Invalid directory specified for --with-shared-memory-dir: $with_shared_memory_dir])
+       ;;
+esac
+
+case x"$with_shared_memory_dir" in
+xyes)
+       AC_MSG_ERROR([No directory found for shared memory temp files.])
+       ;;
+xno)
+       ;;
+*)
+       AC_DEFINE_UNQUOTED(SHMDIR, ["$with_shared_memory_dir"], [Directory for shared memory temp files])
+       ;;
+esac
+
+AC_CONFIG_FILES([Makefile
+                 src/Makefile
+                test/Makefile
+                 xshmfence.pc])
+AC_OUTPUT
diff --git a/packaging/baselibs.conf b/packaging/baselibs.conf
new file mode 100644 (file)
index 0000000..b619f04
--- /dev/null
@@ -0,0 +1 @@
+libxshmfence
diff --git a/packaging/libXshmfence.changes b/packaging/libXshmfence.changes
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/packaging/libXshmfence.manifest b/packaging/libXshmfence.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/libXshmfence.spec b/packaging/libXshmfence.spec
new file mode 100644 (file)
index 0000000..22c042f
--- /dev/null
@@ -0,0 +1,56 @@
+Name:           libXshmfence
+Version:        1.1
+Release:        1
+License:        MIT
+Summary:        X Fixes library
+Url:            http://www.x.org
+Group:          Graphics/X Window System
+Source:         %{name}-%{version}.tar.bz2
+Source1001:    libXshmfence.manifest
+
+BuildRequires:  pkgconfig(xorg-macros)
+BuildRequires:  pkgconfig(xproto)
+
+%description
+X Fixes library.
+
+%package devel
+Summary:        Development files for %{name}
+Group:          Development/Libraries
+Requires:       %{name} = %{version}
+Requires:       pkgconfig
+
+%description devel
+libxshmfence development package
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+%build
+%autogen --disable-static --with-shared-memory-dir=/tmp
+make %{?_smp_mflags}
+
+%install
+mkdir -p %{buildroot}/usr/share/license
+cp -af COPYING %{buildroot}/usr/share/license/%{name}
+%make_install
+%remove_docs
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libxshmfence.so.1
+%{_libdir}/libxshmfence.so.1.0.0
+
+%files devel
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+/usr/share/license/%{name}
+%{_includedir}/X11/xshmfence.h
+%{_libdir}/libxshmfence.so
+%{_libdir}/pkgconfig/xshmfence.pc
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..1a67bdd
--- /dev/null
@@ -0,0 +1,31 @@
+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
+
+if LINT
+ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+               $(AM_CPPFLAGS) $(CPPFLAGS)
+
+lint:
+       $(LINT) $(ALL_LINT_FLAGS) $(libxshmfence_la_SOURCES) $(LIBS)
+endif LINT
diff --git a/src/xshmfence.h b/src/xshmfence.h
new file mode 100644 (file)
index 0000000..27d1b82
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * 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_H_
+#define _XSHMFENCE_H_
+
+#include <X11/Xfuncproto.h>
+
+#define HAVE_STRUCT_XSHMFENCE   1
+
+struct xshmfence;
+
+_X_EXPORT int 
+xshmfence_trigger(struct xshmfence *f);
+
+_X_EXPORT int
+xshmfence_await(struct xshmfence *f);
+
+_X_EXPORT int
+xshmfence_query(struct xshmfence *f);
+
+_X_EXPORT void
+xshmfence_reset(struct xshmfence *f);
+
+_X_EXPORT int
+xshmfence_alloc_shm(void);
+
+_X_EXPORT struct xshmfence *
+xshmfence_map_shm(int fd);
+
+_X_EXPORT void
+xshmfence_unmap_shm(struct xshmfence *f);
+
+#endif /* _XSHMFENCE_H_ */
diff --git a/src/xshmfence_alloc.c b/src/xshmfence_alloc.c
new file mode 100644 (file)
index 0000000..d8d4a40
--- /dev/null
@@ -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 (file)
index 0000000..8b42491
--- /dev/null
@@ -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 (file)
index 0000000..ed60b6d
--- /dev/null
@@ -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/xshmfence_pthread.c b/src/xshmfence_pthread.c
new file mode 100644 (file)
index 0000000..efa5027
--- /dev/null
@@ -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 (file)
index 0000000..9d6b0c8
--- /dev/null
@@ -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
new file mode 100644 (file)
index 0000000..178cbdd
--- /dev/null
@@ -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 _XSHMFENCEINT_H_
+#define _XSHMFENCEINT_H_
+
+#include <stdlib.h>
+#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
new file mode 100644 (file)
index 0000000..57bf1ae
--- /dev/null
@@ -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 @PTHREAD_LIBS@
+
diff --git a/test/xshmfence_test.c b/test/xshmfence_test.c
new file mode 100644 (file)
index 0000000..43ecf2e
--- /dev/null
@@ -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);
+}
diff --git a/xshmfence.pc.in b/xshmfence.pc.in
new file mode 100644 (file)
index 0000000..a139fab
--- /dev/null
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: xshmfence
+Description: The X Shared Memory Fence Library
+Version: @PACKAGE_VERSION@
+Cflags: -I${includedir} @XPROTO_CFLAGS@
+Libs: -L${libdir} -lxshmfence
+Libs.private: @PTHREAD_LIBS@