diff options
-rw-r--r-- | Makefile.am | 41 | ||||
-rwxr-xr-x | autogen.sh | 12 | ||||
-rw-r--r-- | configure.ac | 50 | ||||
-rw-r--r-- | src/Makefile.am | 19 | ||||
-rw-r--r-- | src/xshmfence.c | 144 | ||||
-rw-r--r-- | src/xshmfence.h | 49 | ||||
-rw-r--r-- | src/xshmfenceint.h | 69 | ||||
-rw-r--r-- | xshmfence.pc.in | 10 |
8 files changed, 394 insertions, 0 deletions
diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..92503b3 --- /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 + +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/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..555fdd6 --- /dev/null +++ b/configure.ac @@ -0,0 +1,50 @@ +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.57]) + +AC_INIT(libxshmfence, 0.1, [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], libxshmfence) +AM_INIT_AUTOMAKE([dist-bzip2 foreign]) +AM_MAINTAINER_MODE + +# Require xorg-macros: XORG_CWARNFLAGS, XORG_CHANGELOG, XORG_WITH_LINT +m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.2 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.2) +AM_CONFIG_HEADER(config.h) + +# Check for progs +AC_PROG_CC +AC_PROG_LIBTOOL +XORG_CWARNFLAGS + +dnl Allow checking code with lint, sparse, etc. +XORG_WITH_LINT +LINT_FLAGS="${LINT_FLAGS} ${FONTENC_CFLAGS}" + +XORG_RELEASE_VERSION +XORG_CHANGELOG + +AC_OUTPUT([Makefile + src/Makefile + xshmfence.pc]) diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..90d7bcb --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,19 @@ +lib_LTLIBRARIES = libxshmfence.la + +libxshmfence_la_SOURCES = \ + xshmfence.c + +noinst_HEADERS = xshmfenceint.h + +libxshmfence_la_LDFLAGS = -version-number 1:0:0 -no-undefined + +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) $(libxshmfence_la_LIBADD) $(LIBS) +endif LINT diff --git a/src/xshmfence.c b/src/xshmfence.c new file mode 100644 index 0000000..521d3ad --- /dev/null +++ b/src/xshmfence.c @@ -0,0 +1,144 @@ +/* + * 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 "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(int32_t *f) +{ + if (__sync_val_compare_and_swap(f, 0, 1) == -1) { + atomic_store(f, 1); + if (futex_wake(f) < 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(int32_t *f) +{ + while (__sync_val_compare_and_swap(f, 0, -1) != 1) { + if (futex_wait(f, -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(int32_t *f) +{ + return atomic_fetch(f) == 1; +} + +/** + * xshmfence_reset: + * @f: An X fence + * + * Reset @f to untriggered. If @f is already untriggered, + * this function has no effect. + **/ +void +xshmfence_reset(int32_t *f) +{ + __sync_bool_compare_and_swap(f, 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[] = "/run/shm/shmfd-XXXXXX"; + int fd = mkstemp(template); + + if (fd < 0) + return fd; + unlink(template); + ftruncate(fd, sizeof (int32_t)); + 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). + **/ +int32_t * +xshmfence_map_shm(int fd) +{ + void *addr; + addr = mmap (NULL, sizeof (int32_t) , 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(int32_t *f) +{ + munmap(f, sizeof (int32_t)); +} diff --git a/src/xshmfence.h b/src/xshmfence.h new file mode 100644 index 0000000..f3cbad9 --- /dev/null +++ b/src/xshmfence.h @@ -0,0 +1,49 @@ +/* + * 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 <stdint.h> + +int +xshmfence_trigger(int32_t *f); + +int +xshmfence_await(int32_t *f); + +int +xshmfence_query(int32_t *f); + +void +xshmfence_reset(int32_t *f); + +int +xshmfence_alloc_shm(void); + +int32_t * +xshmfence_map_shm(int fd); + +void +xshmfence_unmap_shm(int32_t *f); + +#endif /* _XSHMFENCE_H_ */ diff --git a/src/xshmfenceint.h b/src/xshmfenceint.h new file mode 100644 index 0000000..3f5c561 --- /dev/null +++ b/src/xshmfenceint.h @@ -0,0 +1,69 @@ +/* + * 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 <stdint.h> +#include <stdio.h> +#include <stddef.h> +#include <stdlib.h> +#include <linux/futex.h> +#include <sys/time.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/mman.h> +#include <errno.h> +#include <values.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; +} + +#endif /* _XSHMFENCEINT_H_ */ diff --git a/xshmfence.pc.in b/xshmfence.pc.in new file mode 100644 index 0000000..cfc1860 --- /dev/null +++ b/xshmfence.pc.in @@ -0,0 +1,10 @@ +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} +Libs: -L${libdir} -lxshmfence |