[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