Module Name:    xsrc
Committed By:   mrg
Date:           Sun Aug 14 03:43:37 UTC 2016

Modified Files:
        xsrc/external/mit/libxshmfence/dist/src: xshmfence_alloc.c
            xshmfenceint.h
Added Files:
        xsrc/external/mit/libxshmfence/dist/src: xshmfence_semaphore.c
            xshmfence_semaphore.h

Log Message:
port across patches from pkgsrc.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r1.2 \
    xsrc/external/mit/libxshmfence/dist/src/xshmfence_alloc.c \
    xsrc/external/mit/libxshmfence/dist/src/xshmfenceint.h
cvs rdiff -u -r0 -r1.1 \
    xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c \
    xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: xsrc/external/mit/libxshmfence/dist/src/xshmfence_alloc.c
diff -u xsrc/external/mit/libxshmfence/dist/src/xshmfence_alloc.c:1.1.1.1 xsrc/external/mit/libxshmfence/dist/src/xshmfence_alloc.c:1.2
--- xsrc/external/mit/libxshmfence/dist/src/xshmfence_alloc.c:1.1.1.1	Sat Aug 13 22:04:04 2016
+++ xsrc/external/mit/libxshmfence/dist/src/xshmfence_alloc.c	Sun Aug 14 03:43:37 2016
@@ -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));
 }
Index: xsrc/external/mit/libxshmfence/dist/src/xshmfenceint.h
diff -u xsrc/external/mit/libxshmfence/dist/src/xshmfenceint.h:1.1.1.1 xsrc/external/mit/libxshmfence/dist/src/xshmfenceint.h:1.2
--- xsrc/external/mit/libxshmfence/dist/src/xshmfenceint.h:1.1.1.1	Sat Aug 13 22:04:04 2016
+++ xsrc/external/mit/libxshmfence/dist/src/xshmfenceint.h	Sun Aug 14 03:43:37 2016
@@ -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

Added files:

Index: xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c
diff -u /dev/null xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c:1.1
--- /dev/null	Sun Aug 14 03:43:37 2016
+++ xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c	Sun Aug 14 03:43:37 2016
@@ -0,0 +1,242 @@
+/*
+ * 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 <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "xshmfenceint.h"
+
+static sem_t *mksemtemp(char *, const char *);
+
+#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) {
+	int v, waiting;
+	LOCK();
+	v = __sync_bool_compare_and_swap(&f->triggered, 0, 1);
+	if (v == 0) {
+		/* already triggered */
+		UNLOCK();
+		return 0;
+	}
+	
+	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.refcnt, 0);
+	__sync_fetch_and_and(&f.triggered, 0);
+	__sync_fetch_and_and(&f.waiting, 0);
+	
+	lock = mksemtemp(f.lockname, "/xshmfl-%i");
+	if (lock == SEM_FAILED) {
+		err(EXIT_FAILURE, "xshmfence_init: sem_open");
+	}
+
+	cond = mksemtemp(f.condname, "/xshmfc-%i");
+	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");
+	}
+	__sync_fetch_and_add(&f->refcnt, 1);
+}
+
+/**
+ * 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);
+	if (__sync_sub_and_fetch(&f->refcnt, 1) == 0) {
+		sem_unlink(f->lockname);
+		sem_unlink(f->condname);
+	}
+}
+
+static sem_t *
+mksemtemp(char *name, const char *template)
+{
+	sem_t *ret;
+	pid_t p;
+	p = getpid();
+	for(;;) {
+		sprintf(name, template, p);
+		ret = sem_open(name, O_CREAT|O_EXCL, 0600, 1);
+		if (ret == SEM_FAILED) {
+			if (errno == EEXIST) {
+				p++;
+				continue;
+			}
+		}
+		return ret;
+	}
+}
Index: xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h
diff -u /dev/null xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h:1.1
--- /dev/null	Sun Aug 14 03:43:37 2016
+++ xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h	Sun Aug 14 03:43:37 2016
@@ -0,0 +1,60 @@
+/*
+ * 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 refcnt LOCK_ALIGN;
+	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_ */

Reply via email to