From 875d73d1b50be59addb994a97f52fd1f448e1fb0 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Mon, 26 Oct 2015 16:05:36 +0900 Subject: [PATCH] tizen 2.4 release --- COPYING | 19 +++++ Makefile.am | 41 +++++++++ README | 36 ++++++++ autogen.sh | 12 +++ configure.ac | 164 ++++++++++++++++++++++++++++++++++++ packaging/baselibs.conf | 1 + packaging/libXshmfence.changes | 1 + packaging/libXshmfence.manifest | 5 ++ packaging/libXshmfence.spec | 56 +++++++++++++ src/Makefile.am | 31 +++++++ src/xshmfence.h | 53 ++++++++++++ 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 | 39 +++++++++ test/Makefile.am | 9 ++ test/xshmfence_test.c | 178 ++++++++++++++++++++++++++++++++++++++++ xshmfence.pc.in | 11 +++ 20 files changed, 1078 insertions(+) create mode 100644 COPYING create mode 100644 Makefile.am create mode 100644 README create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 packaging/baselibs.conf create mode 100644 packaging/libXshmfence.changes create mode 100644 packaging/libXshmfence.manifest create mode 100644 packaging/libXshmfence.spec create mode 100644 src/Makefile.am create mode 100644 src/xshmfence.h create mode 100644 src/xshmfence_alloc.c create mode 100644 src/xshmfence_futex.c create mode 100644 src/xshmfence_futex.h create mode 100644 src/xshmfence_pthread.c create mode 100644 src/xshmfence_pthread.h create mode 100644 src/xshmfenceint.h create mode 100644 test/Makefile.am create mode 100644 test/xshmfence_test.c create mode 100644 xshmfence.pc.in diff --git a/COPYING b/COPYING new file mode 100644 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 index 0000000..670cdcb --- /dev/null +++ b/Makefile.am @@ -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 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 index 0000000..904cd67 --- /dev/null +++ b/autogen.sh @@ -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 index 0000000..8a39f22 --- /dev/null +++ b/configure.ac @@ -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 + 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 index 0000000..b619f04 --- /dev/null +++ b/packaging/baselibs.conf @@ -0,0 +1 @@ +libxshmfence diff --git a/packaging/libXshmfence.changes b/packaging/libXshmfence.changes new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/packaging/libXshmfence.changes @@ -0,0 +1 @@ + diff --git a/packaging/libXshmfence.manifest b/packaging/libXshmfence.manifest new file mode 100644 index 0000000..017d22d --- /dev/null +++ b/packaging/libXshmfence.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/libXshmfence.spec b/packaging/libXshmfence.spec new file mode 100644 index 0000000..22c042f --- /dev/null +++ b/packaging/libXshmfence.spec @@ -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 index 0000000..1a67bdd --- /dev/null +++ b/src/Makefile.am @@ -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 index 0000000..27d1b82 --- /dev/null +++ b/src/xshmfence.h @@ -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 + +#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 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 +#include +#include +#include +#include +#include + +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 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 +#include + +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 index 0000000..178cbdd --- /dev/null +++ b/src/xshmfenceint.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 _XSHMFENCEINT_H_ +#define _XSHMFENCEINT_H_ + +#include +#include +#include +#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 index 0000000..57bf1ae --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,9 @@ +check_PROGRAMS = xshmfence_test + +TESTS=$(check_PROGRAMS) + +xshmfence_test_SOURCES = xshmfence_test.c + +xshmfence_test_CFLAGS = -I$(top_srcdir)/src +xshmfence_test_LDADD = $(top_builddir)/src/libxshmfence.la @PTHREAD_LIBS@ + diff --git a/test/xshmfence_test.c b/test/xshmfence_test.c new file mode 100644 index 0000000..43ecf2e --- /dev/null +++ b/test/xshmfence_test.c @@ -0,0 +1,178 @@ +/* + * Copyright © 2013 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 index 0000000..a139fab --- /dev/null +++ b/xshmfence.pc.in @@ -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@ -- 2.7.4