Module Name:    xsrc
Committed By:   tnn
Date:           Sun Feb 23 23:18:01 UTC 2020

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

Log Message:
sync from pkgsrc:

> libxshmfence: improve performance of semaphore backend. Bump rev.
>
> It used more locking than necessary. We only need two semaphores.
> One to tell waiters to wake up and one to let the last waiter that
> wakes up notify xshmfence_trigger() it may now return.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 \
    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_semaphore.c
diff -u xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c:1.1 xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c:1.2
--- xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c:1.1	Sun Aug 14 03:43:37 2016
+++ xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.c	Sun Feb 23 23:18:01 2020
@@ -33,12 +33,12 @@
 
 #include "xshmfenceint.h"
 
-static sem_t *mksemtemp(char *, const char *);
+static sem_t *mksemtemp(char *, size_t, 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)
+#define COND_WAIT_W() do {} while (sem_wait(f->cond_w) != 0)
+#define COND_SIGNAL_W() do { sem_post(f->cond_w); } while (0)
+#define COND_WAIT_T() do {} while (sem_wait(f->cond_t) != 0)
+#define COND_SIGNAL_T() do { sem_post(f->cond_t); } while (0)
 
 /**
  * xshmfence_trigger:
@@ -52,30 +52,23 @@ static sem_t *mksemtemp(char *, const ch
 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(); */
+	while ((waiting = __sync_fetch_and_add(&f->waiting, 0)) > 0) {
+		if (__sync_bool_compare_and_swap(&f->waiting, waiting, 0)) {
+			__sync_fetch_and_add(&f->wakeups, waiting);
+			while (waiting--) {
+				COND_SIGNAL_W();
+			}
+			COND_WAIT_T();
+			return 0;
+		}
 	}
-	UNLOCK();
+
 	return 0;
 }
 
@@ -92,24 +85,18 @@ xshmfence_trigger(struct xshmfence *f) {
 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();
+		COND_WAIT_W();
+	} while (__sync_fetch_and_add(&f->triggered, 0) == 0);
+
+	if (__sync_sub_and_fetch(&f->wakeups, 1) == 0) {
+		COND_SIGNAL_T();
 	}
-	while (__sync_fetch_and_add(&f->triggered, 0) == 0);
-	UNLOCK();
+
 	return 0;
 }
 
@@ -121,11 +108,7 @@ xshmfence_await(struct xshmfence *f) {
  **/
 int
 xshmfence_query(struct xshmfence *f) {
-	int ret;
-	LOCK();
-	ret = __sync_fetch_and_add(&f->triggered, 0);
-	UNLOCK();
-	return ret;
+	return __sync_fetch_and_add(&f->triggered, 0);
 }
 
 /**
@@ -137,9 +120,7 @@ xshmfence_query(struct xshmfence *f) {
  **/
 void
 xshmfence_reset(struct xshmfence *f) {
-	LOCK();
 	__sync_bool_compare_and_swap(&f->triggered, 1, 0);
-	UNLOCK();
 }
 
 /**
@@ -151,27 +132,26 @@ xshmfence_reset(struct xshmfence *f) {
 void
 xshmfence_init(int fd)
 {
-	sem_t *lock;
-	sem_t *cond;
+	sem_t *cond_w, *cond_t;
 	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) {
+	__sync_fetch_and_and(&f.wakeups, 0);
+
+	cond_w = mksemtemp(f.condname_w, sizeof(f.condname_w), "w");
+	if (cond_w == SEM_FAILED) {
 		err(EXIT_FAILURE, "xshmfence_init: sem_open");
 	}
-
-	cond = mksemtemp(f.condname, "/xshmfc-%i");
-	if (cond == SEM_FAILED) {
+	cond_t = mksemtemp(f.condname_t, sizeof(f.condname_t), "t");
+	if (cond_t == SEM_FAILED) {
 		err(EXIT_FAILURE, "xshmfence_init: sem_open");
 	}
-	
-	sem_close(lock);
-	sem_close(cond);
-	
+
+	sem_close(cond_w);
+	sem_close(cond_t);
+
 	pwrite(fd, &f, sizeof(f), 0);
 }
 
@@ -187,7 +167,7 @@ xshmfence_open_semaphore(struct xshmfenc
 	/*
 	 * map process local memory to page 2
 	 */
-	if (mmap ((void*)&f->lock,
+	if (mmap ((void*)&f->cond_w,
 		  LIBXSHM_PAGESIZE,
 		  PROT_READ|PROT_WRITE,
 		  MAP_FIXED|MAP_ANON,
@@ -195,11 +175,11 @@ xshmfence_open_semaphore(struct xshmfenc
 		errx(EXIT_FAILURE, "xshmfence_open_semaphore: mmap failed");
 	}
 
-	if ((f->lock = sem_open(f->lockname, 0 , 0)) == SEM_FAILED) {
+	if ((f->cond_w = sem_open(f->condname_w, 0)) == SEM_FAILED) {
 		errx(EXIT_FAILURE, "xshmfence_open_semaphore: sem_open failed");
 	}
 
-	if ((f->cond = sem_open(f->condname, 0 , 0)) == SEM_FAILED) {
+	if ((f->cond_t = sem_open(f->condname_t, 0)) == SEM_FAILED) {
 		errx(EXIT_FAILURE, "xshmfence_open_semaphore: sem_open failed");
 	}
 	__sync_fetch_and_add(&f->refcnt, 1);
@@ -214,23 +194,24 @@ xshmfence_open_semaphore(struct xshmfenc
 void
 xshmfence_close_semaphore(struct xshmfence *f)
 {
-	sem_close(f->lock);
-	sem_close(f->cond);
+	sem_close(f->cond_w);
+	sem_close(f->cond_t);
 	if (__sync_sub_and_fetch(&f->refcnt, 1) == 0) {
-		sem_unlink(f->lockname);
-		sem_unlink(f->condname);
+		sem_unlink(f->condname_w);
+		sem_unlink(f->condname_t);
 	}
 }
 
 static sem_t *
-mksemtemp(char *name, const char *template)
+mksemtemp(char *name, size_t namelen, const char *suffix)
 {
 	sem_t *ret;
 	pid_t p;
 	p = getpid();
 	for(;;) {
-		sprintf(name, template, p);
-		ret = sem_open(name, O_CREAT|O_EXCL, 0600, 1);
+		if (snprintf(name, namelen, "/xshmf%s-%d", suffix, p) >= namelen)
+			return SEM_FAILED;
+		ret = sem_open(name, O_CREAT|O_EXCL, 0600, 0);
 		if (ret == SEM_FAILED) {
 			if (errno == EEXIST) {
 				p++;
Index: xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h
diff -u xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h:1.1 xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h:1.2
--- xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h:1.1	Sun Aug 14 03:43:37 2016
+++ xsrc/external/mit/libxshmfence/dist/src/xshmfence_semaphore.h	Sun Feb 23 23:18:01 2020
@@ -43,11 +43,12 @@ struct xshmfence {
 	int refcnt LOCK_ALIGN;
 	int triggered LOCK_ALIGN;
 	int waiting LOCK_ALIGN;
-	char lockname[16];
-	char condname[16];
+	int wakeups LOCK_ALIGN;
+	char condname_w[16];
+	char condname_t[16];
 	/* page 2*/
-	sem_t *lock PAGE_ALIGN;
-	sem_t *cond;
+	sem_t *cond_w PAGE_ALIGN;
+	sem_t *cond_t;
 };
 
 void

Reply via email to