.gitignore | 84 ++++++++++++++++++++ COPYING | 19 ++++ Makefile.am | 2 README | 36 ++++++++ configure.ac | 146 +++++++++++++++++++++++++++++++---- debian/changelog | 7 + debian/libxshmfence1.symbols | 8 + debian/rules | 4 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 20 files changed, 939 insertions(+), 215 deletions(-)
New commits: commit de896051c50a339a9c2131f8ce0d209308c318a5 Author: Maarten Lankhorst <[email protected]> Date: Mon Dec 2 11:29:34 2013 +0100 Bump changelog and add symbols file. diff --git a/debian/changelog b/debian/changelog index 83ca984..304c235 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +libxshmfence (1.1-1) UNRELEASED; urgency=low + + * New upstream release. + * Add symbols file. + + -- Maarten Lankhorst <[email protected]> Mon, 02 Dec 2013 11:07:04 +0100 + libxshmfence (1.0-1) unstable; urgency=low * Initial release. diff --git a/debian/libxshmfence1.symbols b/debian/libxshmfence1.symbols new file mode 100644 index 0000000..fd15ae0 --- /dev/null +++ b/debian/libxshmfence1.symbols @@ -0,0 +1,8 @@ +libxshmfence.so.1 libxshmfence1 #MINVER# + xshmfence_trigger@Base 0 + xshmfence_await@Base 0 + xshmfence_query@Base 0 + xshmfence_reset@Base 0 + xshmfence_alloc_shm@Base 0 + xshmfence_map_shm@Base 0 + xshmfence_unmap_shm@Base 0 diff --git a/debian/rules b/debian/rules index f26c7bd..bcc4344 100755 --- a/debian/rules +++ b/debian/rules @@ -1,6 +1,10 @@ #!/usr/bin/make -f + %: dh $@ --with quilt,autoreconf --builddirectory=build/ +override_dh_makeshlibs: + dh_makeshlibs -- -c4 + override_dh_install: dh_install --fail-missing -X.la commit e8dd66fee206f93e1bee059bdadde064901ed745 Author: Keith Packard <[email protected]> Date: Tue Nov 26 21:55:20 2013 -0800 Update to version 1.1 Signed-off-by: Keith Packard <[email protected]> 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 <[email protected]> Date: Mon Nov 25 13:36:54 2013 -0800 Describe the library better in the README file Signed-off-by: Keith Packard <[email protected]> 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 <[email protected]> Date: Wed Nov 20 14:21:35 2013 -0800 Ignore test build files and release announcements Signed-off-by: Keith Packard <[email protected]> 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 <[email protected]> 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 <[email protected]> Reviewed-by: Adam Jackson <[email protected]> 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 <[email protected]> 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 <[email protected]> Reviewed-by: Adam Jackson <[email protected]> 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 <[email protected]> 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 <[email protected]> Reviewed-by: Adam Jackson <[email protected]> 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); +} -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]

