CVS commit: xsrc/external/mit/libxshmfence/dist/src
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(>triggered, 0, 1); if (v == 0) { /* already triggered */ - UNLOCK(); return 0; } - - waiting = __sync_fetch_and_add(>waiting, 0); - while (waiting > 0) { - COND_SIGNAL(); - waiting--; - } - - while (__sync_fetch_and_add(>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(>waiting, 0)) > 0) { + if (__sync_bool_compare_and_swap(>waiting, waiting, 0)) { + __sync_fetch_and_add(>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(>triggered, 0) == 1) { - UNLOCK(); return 0; } do { __sync_fetch_and_add(>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(>waiting, 1); - LOCK(); + COND_WAIT_W(); + } while (__sync_fetch_and_add(>triggered, 0) == 0); + + if (__sync_sub_and_fetch(>wakeups, 1) == 0) { + COND_SIGNAL_T(); } - while (__sync_fetch_and_add(>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(>triggered, 0); - UNLOCK(); - return ret; + return __sync_fetch_and_add(>triggered, 0); } /** @@ -137,9 +120,7 @@ xshmfence_query(struct xshmfence *f) { **/ void xshmfence_reset(struct xshmfence *f) { - LOCK(); __sync_bool_compare_and_swap(>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(, 0); __sync_fetch_and_and(, 0); __sync_fetch_and_and(, 0); - - lock = mksemtemp(f.lockname, "/xshmfl-%i"); - if (lock == SEM_FAILED) { + __sync_fetch_and_and(, 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, , sizeof(f), 0); } @@ -187,7 +167,7 @@ xshmfence_open_semaphore(struct xshmfenc /* * map process local memory to page 2 */ - if (mmap ((void*)>lock, + if (mmap ((void*)>cond_w, LIBXSHM_PAGESIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_ANON, @@ -195,11 +175,11 @@
CVS commit: xsrc/external/mit/libxshmfence/dist/src
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 +#include +#include +#include +#include + +#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(>triggered, 0, 1); + if (v == 0) { + /* already triggered */ + UNLOCK(); + return 0; + } + + waiting = __sync_fetch_and_add(>waiting, 0); + + while (waiting > 0) { + COND_SIGNAL(); + waiting--; + } + + while (__sync_fetch_and_add(>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 + *