[PATCH 5/7] Split out futex implementation from general API
Keith Packard
keithp at keithp.com
Wed Nov 20 11:55:59 PST 2013
This splits the futex-specific code out into a separate file so that
future versions of the library could use some other underlying primitive.
Signed-off-by: Keith Packard <keithp at keithp.com>
---
src/Makefile.am | 7 ++-
src/xshmfence.c | 158 --------------------------------------------------
src/xshmfence_alloc.c | 88 ++++++++++++++++++++++++++++
src/xshmfence_futex.c | 94 ++++++++++++++++++++++++++++++
src/xshmfence_futex.h | 70 ++++++++++++++++++++++
src/xshmfenceint.h | 42 +-------------
6 files changed, 258 insertions(+), 201 deletions(-)
delete mode 100644 src/xshmfence.c
create mode 100644 src/xshmfence_alloc.c
create mode 100644 src/xshmfence_futex.c
create mode 100644 src/xshmfence_futex.h
diff --git a/src/Makefile.am b/src/Makefile.am
index 90d7bcb..d817326 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,9 +1,12 @@
lib_LTLIBRARIES = libxshmfence.la
+FUTEX_SOURCES=xshmfence_futex.c
+
libxshmfence_la_SOURCES = \
- xshmfence.c
+ xshmfence_alloc.c \
+ $(FUTEX_SOURCES)
-noinst_HEADERS = xshmfenceint.h
+noinst_HEADERS = xshmfence_futex.h xshmfenceint.h
libxshmfence_la_LDFLAGS = -version-number 1:0:0 -no-undefined
diff --git a/src/xshmfence.c b/src/xshmfence.c
deleted file mode 100644
index ed2b4c4..0000000
--- a/src/xshmfence.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright © 2013 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "xshmfenceint.h"
-
-struct xshmfence {
- int32_t v;
-};
-
-/**
- * xshmfence_trigger:
- * @f: An X fence
- *
- * Set @f to triggered, waking all waiters.
- *
- * Return value: 0 on success and -1 on error (in which case, errno
- * will be set as appropriate).
- **/
-int
-xshmfence_trigger(struct xshmfence *f)
-{
- if (__sync_val_compare_and_swap(&f->v, 0, 1) == -1) {
- atomic_store(&f->v, 1);
- if (futex_wake(&f->v) < 0)
- return -1;
- }
- return 0;
-}
-
-/**
- * xshmfence_await:
- * @f: An X fence
- *
- * Wait for @f to be triggered. If @f is already triggered, this
- * function returns immediately.
- *
- * Return value: 0 on success and -1 on error (in which case, errno
- * will be set as appropriate).
- **/
-int
-xshmfence_await(struct xshmfence *f)
-{
- while (__sync_val_compare_and_swap(&f->v, 0, -1) != 1) {
- if (futex_wait(&f->v, -1)) {
- if (errno != EWOULDBLOCK)
- return -1;
- }
- }
- return 0;
-}
-
-/**
- * xshmfence_query:
- * @f: An X fence
- *
- * Return value: 1 if @f is triggered, else returns 0.
- **/
-int
-xshmfence_query(struct xshmfence *f)
-{
- return atomic_fetch(&f->v) == 1;
-}
-
-/**
- * xshmfence_reset:
- * @f: An X fence
- *
- * Reset @f to untriggered. If @f is already untriggered,
- * this function has no effect.
- **/
-void
-xshmfence_reset(struct xshmfence *f)
-{
- __sync_bool_compare_and_swap(&f->v, 1, 0);
-}
-
-/**
- * xshmfence_alloc_shm:
- *
- * Allocates a shared memory object large enough to hold a single
- * fence.
- *
- * Return value: the file descriptor of the object, or -1 on failure
- * (in which case, errno will be set as appropriate).
- **/
-int
-xshmfence_alloc_shm(void)
-{
- char template[] = SHMDIR "/shmfd-XXXXXX";
- int fd;
-
-#ifdef O_TMPFILE
- fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666);
- if (fd < 0)
-#endif
- {
- fd = mkstemp(template);
- if (fd < 0)
- return fd;
- unlink(template);
- }
- ftruncate(fd, sizeof (struct xshmfence));
- return fd;
-}
-
-/**
- * xshmfence_map_shm:
- *
- * Map a shared memory fence referenced by @fd.
- *
- * Return value: the fence or NULL (in which case, errno will be set
- * as appropriate).
- **/
-struct xshmfence *
-xshmfence_map_shm(int fd)
-{
- struct xshmfence *addr;
- addr = mmap (NULL, sizeof (struct xshmfence) , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
- if (addr == MAP_FAILED) {
- close (fd);
- return 0;
- }
- return addr;
-}
-
-/**
- * xshmfence_unmap_shm:
- *
- * Unap a shared memory fence @f.
- **/
-void
-xshmfence_unmap_shm(struct xshmfence *f)
-{
- munmap(f, sizeof (struct xshmfence));
-}
diff --git a/src/xshmfence_alloc.c b/src/xshmfence_alloc.c
new file mode 100644
index 0000000..d8d4a40
--- /dev/null
+++ b/src/xshmfence_alloc.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xshmfenceint.h"
+
+/**
+ * xshmfence_alloc_shm:
+ *
+ * Allocates a shared memory object large enough to hold a single
+ * fence.
+ *
+ * Return value: the file descriptor of the object, or -1 on failure
+ * (in which case, errno will be set as appropriate).
+ **/
+int
+xshmfence_alloc_shm(void)
+{
+ char template[] = SHMDIR "/shmfd-XXXXXX";
+ int fd;
+
+#ifdef O_TMPFILE
+ fd = open(SHMDIR, O_TMPFILE|O_RDWR|O_CLOEXEC|O_EXCL, 0666);
+ if (fd < 0)
+#endif
+ {
+ fd = mkstemp(template);
+ if (fd < 0)
+ return fd;
+ unlink(template);
+ }
+ ftruncate(fd, sizeof (struct xshmfence));
+ xshmfence_init(fd);
+ return fd;
+}
+
+/**
+ * xshmfence_map_shm:
+ *
+ * Map a shared memory fence referenced by @fd.
+ *
+ * Return value: the fence or NULL (in which case, errno will be set
+ * as appropriate).
+ **/
+struct xshmfence *
+xshmfence_map_shm(int fd)
+{
+ struct xshmfence *addr;
+ addr = mmap (NULL, sizeof (struct xshmfence) , PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ close (fd);
+ return 0;
+ }
+ return addr;
+}
+
+/**
+ * xshmfence_unmap_shm:
+ *
+ * Unap a shared memory fence @f.
+ **/
+void
+xshmfence_unmap_shm(struct xshmfence *f)
+{
+ munmap(f, sizeof (struct xshmfence));
+}
diff --git a/src/xshmfence_futex.c b/src/xshmfence_futex.c
new file mode 100644
index 0000000..8b42491
--- /dev/null
+++ b/src/xshmfence_futex.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "xshmfenceint.h"
+
+/**
+ * xshmfence_trigger:
+ * @f: An X fence
+ *
+ * Set @f to triggered, waking all waiters.
+ *
+ * Return value: 0 on success and -1 on error (in which case, errno
+ * will be set as appropriate).
+ **/
+int
+xshmfence_trigger(struct xshmfence *f)
+{
+ if (__sync_val_compare_and_swap(&f->v, 0, 1) == -1) {
+ atomic_store(&f->v, 1);
+ if (futex_wake(&f->v) < 0)
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * xshmfence_await:
+ * @f: An X fence
+ *
+ * Wait for @f to be triggered. If @f is already triggered, this
+ * function returns immediately.
+ *
+ * Return value: 0 on success and -1 on error (in which case, errno
+ * will be set as appropriate).
+ **/
+int
+xshmfence_await(struct xshmfence *f)
+{
+ while (__sync_val_compare_and_swap(&f->v, 0, -1) != 1) {
+ if (futex_wait(&f->v, -1)) {
+ if (errno != EWOULDBLOCK)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/**
+ * xshmfence_query:
+ * @f: An X fence
+ *
+ * Return value: 1 if @f is triggered, else returns 0.
+ **/
+int
+xshmfence_query(struct xshmfence *f)
+{
+ return atomic_fetch(&f->v) == 1;
+}
+
+/**
+ * xshmfence_reset:
+ * @f: An X fence
+ *
+ * Reset @f to untriggered. If @f is already untriggered,
+ * this function has no effect.
+ **/
+void
+xshmfence_reset(struct xshmfence *f)
+{
+ __sync_bool_compare_and_swap(&f->v, 1, 0);
+}
diff --git a/src/xshmfence_futex.h b/src/xshmfence_futex.h
new file mode 100644
index 0000000..ed60b6d
--- /dev/null
+++ b/src/xshmfence_futex.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2013 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifndef _XSHMFENCE_FUTEX_H_
+#define _XSHMFENCE_FUTEX_H_
+
+#include <errno.h>
+#include <stdint.h>
+#include <values.h>
+#include <linux/futex.h>
+#include <sys/time.h>
+#include <sys/syscall.h>
+
+static inline long sys_futex(void *addr1, int op, int val1, struct timespec *timeout, void *addr2, int val3)
+{
+ return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
+}
+
+static inline int futex_wake(int32_t *addr) {
+ return sys_futex(addr, FUTEX_WAKE, MAXINT, NULL, NULL, 0);
+}
+
+static inline int futex_wait(int32_t *addr, int32_t value) {
+ return sys_futex(addr, FUTEX_WAIT, value, NULL, NULL, 0);
+}
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+static inline void atomic_store(int32_t *f, int32_t v)
+{
+ barrier();
+ *f = v;
+ barrier();
+}
+
+static inline int32_t atomic_fetch(int32_t *a)
+{
+ int32_t v;
+ barrier();
+ v = *a;
+ barrier();
+ return v;
+}
+
+struct xshmfence {
+ int32_t v;
+};
+
+#define xshmfence_init(fd)
+
+#endif /* _XSHMFENCE_FUTEX_H_ */
diff --git a/src/xshmfenceint.h b/src/xshmfenceint.h
index 66862d0..3452a55 100644
--- a/src/xshmfenceint.h
+++ b/src/xshmfenceint.h
@@ -23,50 +23,10 @@
#ifndef _XSHMFENCEINT_H_
#define _XSHMFENCEINT_H_
-#include <stdint.h>
-#include <stdio.h>
-#include <stddef.h>
#include <stdlib.h>
-#include <linux/futex.h>
-#include <sys/time.h>
#include <unistd.h>
-#include <sys/syscall.h>
#include <sys/mman.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <values.h>
#include "xshmfence.h"
+#include "xshmfence_futex.h"
-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_ */
--
1.8.4.2
More information about the xorg-devel
mailing list