summaryrefslogtreecommitdiff
path: root/x11
diff options
context:
space:
mode:
authortnn <tnn@pkgsrc.org>2015-09-24 23:34:16 +0000
committertnn <tnn@pkgsrc.org>2015-09-24 23:34:16 +0000
commit1b09f247442e3673a275fd65cdccd524b4c11a46 (patch)
tree79ce2dcac4a2b08e5b00507003cc741ae70a7452 /x11
parent49074949baf9dabd3bd2bfa14b409972364c5d0c (diff)
downloadpkgsrc-1b09f247442e3673a275fd65cdccd524b4c11a46.tar.gz
Add makeshift NetBSD support using POSIX semaphores.
Not upstreamed because I think NetBSD should be given the chance to implement some better interprocess synchronization primitives first. See PR lib/49529. In particular what's missing is an interprocess sync primitive that can: 1) be passed safely through MAP_SHARED memory 2) support atomic unlock-and-block (like pthread_cond_wait) 3) wake up all waiters at once
Diffstat (limited to 'x11')
-rw-r--r--x11/libxshmfence/DESCR6
-rw-r--r--x11/libxshmfence/Makefile23
-rw-r--r--x11/libxshmfence/distinfo6
-rw-r--r--x11/libxshmfence/files/xshmfence_semaphore.c217
-rw-r--r--x11/libxshmfence/files/xshmfence_semaphore.h59
-rw-r--r--x11/libxshmfence/patches/patch-configure.ac53
-rw-r--r--x11/libxshmfence/patches/patch-src_Makefile.am23
-rw-r--r--x11/libxshmfence/patches/patch-src_xshmfence__alloc.c23
-rw-r--r--x11/libxshmfence/patches/patch-src_xshmfenceint.h15
9 files changed, 416 insertions, 9 deletions
diff --git a/x11/libxshmfence/DESCR b/x11/libxshmfence/DESCR
index beb0029e337..8a84bf8fcc3 100644
--- a/x11/libxshmfence/DESCR
+++ b/x11/libxshmfence/DESCR
@@ -2,11 +2,13 @@ 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 three underlying implementations:
+There are four underlying implementations:
1) On Linux, the library uses futexes
2) On FreeBSD, the library uses umtx
- 3) On other systems, the library uses posix mutexes and condition
+ 3) On NetBSD, the library uses POSIX semaphores (for now)
+
+ 4) On other systems, the library uses posix mutexes and condition
variables.
diff --git a/x11/libxshmfence/Makefile b/x11/libxshmfence/Makefile
index 5d8d0f3ca72..513f1ee0b7b 100644
--- a/x11/libxshmfence/Makefile
+++ b/x11/libxshmfence/Makefile
@@ -1,6 +1,7 @@
-# $NetBSD: Makefile,v 1.2 2015/09/16 18:38:34 jperkin Exp $
+# $NetBSD: Makefile,v 1.3 2015/09/24 23:34:16 tnn Exp $
DISTNAME= libxshmfence-1.2
+PKGREVISION= 1
CATEGORIES= x11
MASTER_SITES= http://xorg.freedesktop.org/archive/individual/lib/
EXTRACT_SUFX= .tar.bz2
@@ -12,15 +13,25 @@ LICENSE= mit
GNU_CONFIGURE= yes
USE_LIBTOOL= yes
-USE_TOOLS+= pkg-config
+USE_TOOLS+= pkg-config autoconf automake autoreconf
PKGCONFIG_OVERRIDE+= xshmfence.pc.in
-# Needs additional pthread functions or alternative synchronization
-# implementation on NetBSD. See PR lib/49529.
-# (On FreeBSD, umtx is used.)
+.include "../../mk/bsd.prefs.mk"
-ONLY_FOR_PLATFORM+= Linux-*-* FreeBSD-*-* SunOS-*-*
+.if ${OPSYS} == "NetBSD"
+CONFIGURE_ARGS+= --disable-futex
+CONFIGURE_ARGS+= --enable-semaphore
+LIBXSHM_PAGESIZE!= /sbin/sysctl -n hw.pagesize
+CPPFLAGS+= -DLIBXSHM_PAGESIZE=${LIBXSHM_PAGESIZE}
+.endif
+post-extract:
+ cp ${FILESDIR}/xshmfence_semaphore.[ch] ${WRKSRC}/src
+
+pre-configure:
+ cd ${WRKSRC} && autoreconf -vif
+
+.include "../../devel/xorg-util-macros/buildlink3.mk"
.include "../../x11/xproto/buildlink3.mk"
.include "../../mk/bsd.pkg.mk"
diff --git a/x11/libxshmfence/distinfo b/x11/libxshmfence/distinfo
index 8c4bea7ccc9..00c5c2be272 100644
--- a/x11/libxshmfence/distinfo
+++ b/x11/libxshmfence/distinfo
@@ -1,5 +1,9 @@
-$NetBSD: distinfo,v 1.1 2015/04/29 14:31:42 tnn Exp $
+$NetBSD: distinfo,v 1.2 2015/09/24 23:34:16 tnn Exp $
SHA1 (libxshmfence-1.2.tar.bz2) = a2ebe90e5595afca4db93a4359732af43b2b8c69
RMD160 (libxshmfence-1.2.tar.bz2) = fe4b42d4ee01a993cd653d8f10334069bcc4791c
Size (libxshmfence-1.2.tar.bz2) = 267170 bytes
+SHA1 (patch-configure.ac) = 9301700c19d55b0c80f0265274ea6a158657d039
+SHA1 (patch-src_Makefile.am) = cdf80a7606cbc91ddca1443cd9210a3480de5241
+SHA1 (patch-src_xshmfence__alloc.c) = 355c20c55601c4ea71306d1e10cbd632b2d7f393
+SHA1 (patch-src_xshmfenceint.h) = 1996a0c18977c1e0f05fda3248ed3e97a181f6f1
diff --git a/x11/libxshmfence/files/xshmfence_semaphore.c b/x11/libxshmfence/files/xshmfence_semaphore.c
new file mode 100644
index 00000000000..714d5b64399
--- /dev/null
+++ b/x11/libxshmfence/files/xshmfence_semaphore.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2015 Tobias Nygren
+ * 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 <fcntl.h>
+#include <string.h>
+#include <err.h>
+#include <unistd.h>
+
+#include "xshmfenceint.h"
+
+#define LOCK() do {} while (sem_wait(f->lock) != 0)
+#define UNLOCK() do { sem_post(f->lock); } while (0)
+#define COND_WAIT() do {} while (sem_wait(f->cond) != 0)
+#define COND_SIGNAL() do { sem_post(f->cond); } while (0)
+
+/**
+ * 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) {
+ LOCK();
+ int v = __sync_bool_compare_and_swap(&f->triggered, 0, 1);
+ if (v == 0) {
+ /* already triggered */
+ UNLOCK();
+ return 0;
+ }
+
+ int waiting = __sync_fetch_and_add(&f->waiting, 0);
+
+ while (waiting > 0) {
+ COND_SIGNAL();
+ waiting--;
+ }
+
+ while (__sync_fetch_and_add(&f->waiting, 0) > 0) {
+ /*
+ * Busy wait until they all woke up.
+ * No new sleepers should arrive since
+ * the lock is still held.
+ */
+ /* yield(); */
+ }
+ UNLOCK();
+ 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) {
+
+ LOCK();
+ if (__sync_fetch_and_add(&f->triggered, 0) == 1) {
+ UNLOCK();
+ return 0;
+ }
+ do {
+ __sync_fetch_and_add(&f->waiting, 1);
+ /*
+ * These next operations are not atomic.
+ * But we busy-wait in xshmfence_trigger, so that's ok.
+ */
+ UNLOCK();
+ COND_WAIT();
+ __sync_fetch_and_sub(&f->waiting, 1);
+ LOCK();
+ }
+ while (__sync_fetch_and_add(&f->triggered, 0) == 0);
+ UNLOCK();
+ 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 ret;
+ LOCK();
+ ret = __sync_fetch_and_add(&f->triggered, 0);
+ UNLOCK();
+ return ret;
+}
+
+/**
+ * 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) {
+ LOCK();
+ __sync_bool_compare_and_swap(&f->triggered, 1, 0);
+ UNLOCK();
+}
+
+/**
+ * xshmfence_init:
+ * @fd: An fd for an X fence
+ *
+ * Initialize the fence when first allocated
+ **/
+void
+xshmfence_init(int fd)
+{
+ sem_t *lock;
+ sem_t *cond;
+ struct xshmfence f;
+
+ __sync_fetch_and_and(&f.triggered, 0);
+ __sync_fetch_and_and(&f.waiting, 0);
+
+ strlcpy(f.lockname, "/xshmfl-XXXX", sizeof(f.lockname));
+ mktemp(f.lockname);
+ lock = sem_open(f.lockname, O_CREAT|O_EXCL, 0600, 1);
+ if (lock == SEM_FAILED) {
+ err(EXIT_FAILURE, "xshmfence_init: sem_open");
+ }
+
+ strlcpy(f.condname, "/xshmfc-XXXX", sizeof(f.condname));
+ mktemp(f.condname);
+ cond = sem_open(f.condname, O_CREAT|O_EXCL, 0600, 0);
+ if (cond == SEM_FAILED) {
+ err(EXIT_FAILURE, "xshmfence_init: sem_open");
+ }
+
+ sem_close(lock);
+ sem_close(cond);
+
+ pwrite(fd, &f, sizeof(f), 0);
+}
+
+/**
+ * xshmfence_open_semaphore:
+ * @f: An X fence
+ *
+ * Open the semaphore after mapping the fence
+ **/
+void
+xshmfence_open_semaphore(struct xshmfence *f)
+{
+ /*
+ * map process local memory to page 2
+ */
+ if (mmap ((void*)&f->lock,
+ LIBXSHM_PAGESIZE,
+ PROT_READ|PROT_WRITE,
+ MAP_FIXED|MAP_ANON,
+ -1, 0) == MAP_FAILED) {
+ errx(EXIT_FAILURE, "xshmfence_open_semaphore: mmap failed");
+ }
+
+ if ((f->lock = sem_open(f->lockname, 0 , 0)) == SEM_FAILED) {
+ errx(EXIT_FAILURE, "xshmfence_open_semaphore: sem_open failed");
+ }
+
+ if ((f->cond = sem_open(f->condname, 0 , 0)) == SEM_FAILED) {
+ errx(EXIT_FAILURE, "xshmfence_open_semaphore: sem_open failed");
+ }
+}
+
+/**
+ * xshmfence_close_semaphore:
+ * @f: An X fence
+ *
+ * Close the semaphore before unmapping the fence
+ **/
+void
+xshmfence_close_semaphore(struct xshmfence *f)
+{
+ sem_close(f->lock);
+ sem_close(f->cond);
+}
diff --git a/x11/libxshmfence/files/xshmfence_semaphore.h b/x11/libxshmfence/files/xshmfence_semaphore.h
new file mode 100644
index 00000000000..5b3df110044
--- /dev/null
+++ b/x11/libxshmfence/files/xshmfence_semaphore.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2015 Tobias Nygren
+ * 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_SEMAPHORE_H_
+#define _XSHMFENCE_SEMAPHORE_H_
+
+#include <semaphore.h>
+
+#define LOCK_ALIGN __attribute__((aligned(128)))
+#ifndef LIBXSHM_PAGESIZE
+#error unknown machine page size
+#endif
+#define PAGE_ALIGN __attribute__((aligned(LIBXSHM_PAGESIZE)))
+
+/*
+ * the fence is divided into two memory pages:
+ * page 1 contains process shared state
+ * page 2 contains process local state
+ */
+
+struct xshmfence {
+ /* page 1 */
+ int triggered LOCK_ALIGN;
+ int waiting LOCK_ALIGN;
+ char lockname[16];
+ char condname[16];
+ /* page 2*/
+ sem_t *lock PAGE_ALIGN;
+ sem_t *cond;
+};
+
+void
+xshmfence_init(int fd);
+void
+xshmfence_open_semaphore(struct xshmfence *f);
+void
+xshmfence_close_semaphore(struct xshmfence *f);
+
+#endif /* _XSHMFENCE_SEMAPHORE_H_ */
diff --git a/x11/libxshmfence/patches/patch-configure.ac b/x11/libxshmfence/patches/patch-configure.ac
new file mode 100644
index 00000000000..b1235f795ca
--- /dev/null
+++ b/x11/libxshmfence/patches/patch-configure.ac
@@ -0,0 +1,53 @@
+$NetBSD: patch-configure.ac,v 1.1 2015/09/24 23:34:16 tnn Exp $
+
+--- configure.ac.orig 2015-01-02 18:43:42.000000000 +0000
++++ configure.ac
+@@ -52,6 +52,9 @@ dnl
+ AC_ARG_ENABLE(futex, AS_HELP_STRING([--enable-futex], [Enable futexes (default: auto)]),
+ [FUTEX=$enableval], [FUTEX=auto])
+
++AC_ARG_ENABLE(semaphore, AS_HELP_STRING([--enable-semaphore], [Enable POSIX named semaphores (default: no)]),
++ [SEMAPHORE=$enableval], [FUTEX=no])
++
+ if test "x$FUTEX" = "xauto"; then
+ AC_CHECK_HEADER([linux/futex.h], [FUTEX=yes])
+ fi
+@@ -65,23 +68,36 @@ if test "x$FUTEX" = "xauto"; then
+ fi
+ fi
+
++if test "x$SEMAPHORE" = "xyes"; then
++ AC_CHECK_HEADER([semaphore.h], [], [AC_MSG_ERROR([No platform support for POSIX named semaphores])])
++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])
++ if test "x$SEMAPHORE" = "xyes"; then
++ PTHREAD=no
++ AC_DEFINE(HAVE_SEMAPHORE,1,[Use semaphores])
++ else
++ PTHREAD=yes
++ AC_DEFINE(HAVE_PTHREAD,1,[Use pthread primitives])
++ fi
+ fi
+
+ PTHREAD_LIBS=
+ if test "x$PTHREAD" = "xyes"; then
+ AC_CHECK_LIB(pthread,pthread_create,[PTHREAD_LIBS=-lpthread],[PTHREAD_LIBS=])
+ fi
++if test "x$SEMAPHORE" = "xyes"; then
++ AC_CHECK_LIB(rt,sem_open,[PTHREAD_LIBS=-lrt])
++fi
+
+ AC_SUBST([PTHREAD_LIBS])
+
+ AM_CONDITIONAL([FUTEX], [test x"$FUTEX" = xyes])
+ AM_CONDITIONAL([PTHREAD], [test x"$PTHREAD" = xyes])
++AM_CONDITIONAL([SEMAPHORE], [test x"$SEMAPHORE" = xyes])
+
+ PKG_CHECK_MODULES(XPROTO, xproto)
+
diff --git a/x11/libxshmfence/patches/patch-src_Makefile.am b/x11/libxshmfence/patches/patch-src_Makefile.am
new file mode 100644
index 00000000000..6b8e1d62702
--- /dev/null
+++ b/x11/libxshmfence/patches/patch-src_Makefile.am
@@ -0,0 +1,23 @@
+$NetBSD: patch-src_Makefile.am,v 1.1 2015/09/24 23:34:16 tnn Exp $
+
+--- src/Makefile.am.orig 2013-12-02 21:07:56.000000000 +0000
++++ src/Makefile.am
+@@ -4,6 +4,10 @@ if PTHREAD
+ PTHREAD_SOURCES=xshmfence_pthread.c xshmfence_pthread.h
+ endif
+
++if SEMAPHORE
++SEMAPHORE_SOURCES=xshmfence_semaphore.c xshmfence_semaphore.h
++endif
++
+ if FUTEX
+ FUTEX_SOURCES=xshmfence_futex.c xshmfence_futex.h
+ endif
+@@ -12,6 +16,7 @@ libxshmfence_la_SOURCES = \
+ xshmfenceint.h \
+ xshmfence_alloc.c \
+ $(PTHREAD_SOURCES) \
++ $(SEMAPHORE_SOURCES) \
+ $(FUTEX_SOURCES)
+
+ AM_CFLAGS = $(CWARNFLAGS)
diff --git a/x11/libxshmfence/patches/patch-src_xshmfence__alloc.c b/x11/libxshmfence/patches/patch-src_xshmfence__alloc.c
new file mode 100644
index 00000000000..62553411e8c
--- /dev/null
+++ b/x11/libxshmfence/patches/patch-src_xshmfence__alloc.c
@@ -0,0 +1,23 @@
+$NetBSD: patch-src_xshmfence__alloc.c,v 1.1 2015/09/24 23:34:16 tnn Exp $
+
+--- src/xshmfence_alloc.c.orig 2014-10-09 12:09:03.000000000 +0000
++++ src/xshmfence_alloc.c
+@@ -110,6 +110,9 @@ xshmfence_map_shm(int fd)
+ close (fd);
+ return 0;
+ }
++#ifdef HAVE_SEMAPHORE
++ xshmfence_open_semaphore(addr);
++#endif
+ return addr;
+ }
+
+@@ -121,5 +124,8 @@ xshmfence_map_shm(int fd)
+ void
+ xshmfence_unmap_shm(struct xshmfence *f)
+ {
++#ifdef HAVE_SEMAPHORE
++ xshmfence_close_semaphore(f);
++#endif
+ munmap(f, sizeof (struct xshmfence));
+ }
diff --git a/x11/libxshmfence/patches/patch-src_xshmfenceint.h b/x11/libxshmfence/patches/patch-src_xshmfenceint.h
new file mode 100644
index 00000000000..1ef00c85bfc
--- /dev/null
+++ b/x11/libxshmfence/patches/patch-src_xshmfenceint.h
@@ -0,0 +1,15 @@
+$NetBSD: patch-src_xshmfenceint.h,v 1.1 2015/09/24 23:34:16 tnn Exp $
+
+--- src/xshmfenceint.h.orig 2013-12-02 21:07:56.000000000 +0000
++++ src/xshmfenceint.h
+@@ -32,6 +32,10 @@
+ #include "xshmfence_futex.h"
+ #endif
+
++#if HAVE_SEMAPHORE
++#include "xshmfence_semaphore.h"
++#endif
++
+ #if HAVE_PTHREAD
+ #include "xshmfence_pthread.h"
+ #endif