proplib: use GCC atomic builtins if supported.

This commit is contained in:
Juan RP 2014-10-09 14:41:43 +02:00
parent 09c630a825
commit fe76af7702
3 changed files with 65 additions and 12 deletions

6
NEWS
View File

@ -1,3 +1,9 @@
xbps-0.42 (???):
* Use atomic builtins if supported by the compiler in our
portableproplib copy, to handle object reference counting.
This should be cheaper than using a mutex.
xbps-0.41 (2014-09-29): xbps-0.41 (2014-09-29):
* libxbps: another bugfix while checking required shlibs in * libxbps: another bugfix while checking required shlibs in

25
configure vendored
View File

@ -340,6 +340,31 @@ echo "CPPFLAGS += -I\$(TOPDIR)/lib/portableproplib/prop" >>$CONFIG_MK
echo "LDFLAGS += -lpthread" >>$CONFIG_MK echo "LDFLAGS += -lpthread" >>$CONFIG_MK
echo "STATIC_LIBS += -lpthread" >>$CONFIG_MK echo "STATIC_LIBS += -lpthread" >>$CONFIG_MK
#
# Check for GCC atomic builtins.
#
func=atomic
printf "Checking for GCC atomic builtins ... "
cat <<EOF >_$func.c
int main() {
volatile unsigned long val = 1;
__sync_fetch_and_add(&val, 1);
__sync_fetch_and_sub(&val, 1);
__sync_add_and_fetch(&val, 1);
__sync_sub_and_fetch(&val, 1);
return 0;
}
EOF
if $XCC _$func.c -o _$func 2>/dev/null; then
echo yes.
HAVE_ATOMICS=1
else
echo no.
fi
rm -f _$func.c _$func
if test -n "$HAVE_ATOMICS"; then
echo "CPPFLAGS += -DHAVE_ATOMICS" >> $CONFIG_MK
fi
# #
# Check for vasprintf(). # Check for vasprintf().
# #

View File

@ -277,36 +277,58 @@ struct _prop_object_iterator {
static pthread_once_t x = PTHREAD_ONCE_INIT; static pthread_once_t x = PTHREAD_ONCE_INIT;
#define _PROP_ONCE_RUN(x,f) pthread_once(&(x),(void(*)(void))f) #define _PROP_ONCE_RUN(x,f) pthread_once(&(x),(void(*)(void))f)
#ifndef HAVE_ATOMICS /* NO ATOMIC SUPPORT, USE A MUTEX */
#define _PROP_NEED_REFCNT_MTX #define _PROP_NEED_REFCNT_MTX
#define _PROP_ATOMIC_INC32(x) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
(*(x))++; \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32(x) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
(*(x))--; \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_INC32_NV(x, v) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
v = ++(*(x)); \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32_NV(x, v) \
do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \
v = --(*(x)); \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0)
#else /* GCC ATOMIC BUILTINS */
#define _PROP_ATOMIC_INC32(x) \ #define _PROP_ATOMIC_INC32(x) \
do { \ do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \ (void)__sync_fetch_and_add(x, 1); \
(*(x))++; \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32(x) \ #define _PROP_ATOMIC_DEC32(x) \
do { \ do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \ (void)__sync_fetch_and_sub(x, 1); \
(*(x))--; \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_INC32_NV(x, v) \ #define _PROP_ATOMIC_INC32_NV(x, v) \
do { \ do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \ v = __sync_add_and_fetch(x, 1); \
v = ++(*(x)); \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#define _PROP_ATOMIC_DEC32_NV(x, v) \ #define _PROP_ATOMIC_DEC32_NV(x, v) \
do { \ do { \
pthread_mutex_lock(&_prop_refcnt_mtx); \ v = __sync_sub_and_fetch(x, 1); \
v = --(*(x)); \
pthread_mutex_unlock(&_prop_refcnt_mtx); \
} while (/*CONSTCOND*/0) } while (/*CONSTCOND*/0)
#endif /* !HAVE_ATOMICS */
/* /*
* Language features. * Language features.
*/ */