From 9c2cc9bb2feaca5fa853096b15161f8faa4da89d Mon Sep 17 00:00:00 2001 From: Alexander Vdolainen Date: Wed, 30 Dec 2015 02:25:09 +0200 Subject: [PATCH] CAS workaround; --- configure.ac | 32 ++++++++++++++++++++++++++++++- lib/Makefile.am | 3 ++- lib/cas.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 lib/cas.c diff --git a/configure.ac b/configure.ac index fa0228b..fba0023 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(libtdata, 0.2.2) +AC_INIT(libtdata, 0.2.3) AC_CONFIG_HEADERS([config.h]) @@ -12,6 +12,36 @@ AC_PROG_CC LT_INIT +# Checks for pointer size. +# TODO: Later this is irrelevant, and we should just bail on 32-bit platforms always +AC_CHECK_SIZEOF([uintptr_t]) +if test "x$ac_cv_sizeof_uintptr_t" == "x"; then + AC_ERROR([Cannot determine size of uintptr_t]) +fi +AC_SUBST(ac_cv_sizeof_uintptr_t) + +if test "${ac_cv_sizeof_uintptr_t}" = "4"; then + AC_DEFINE([BUILD_HOST_32BIT], 1, [Define to 1 if host is 32bit]) +fi + +dnl ************************************** +dnl ***** tests for compiler built-ins ***** +dnl ************************************** + +AC_CACHE_CHECK([for __sync_bool_compare_and_swap_8], +[ctrie_cv_func___sync_bool_compare_and_swap_8], +[AC_LINK_IFELSE([ +typedef unsigned int uint64 __attribute__ ((mode (DI))); +uint64 i; +int main() { return __sync_bool_compare_and_swap (&i, 0, 1); } +], +[ctrie_cv_func___sync_bool_compare_and_swap_8=yes], +[ctrie_cv_func___sync_bool_compare_and_swap_8=no])]) +if test "$ctrie_cv_func___sync_bool_compare_and_swap_8" = "yes"; then + AC_DEFINE([HAVE__SYNC_BOOL_COMPARE_AND_SWAP_8], 1, + [Define to 1 if the compiler provides the __sync_bool_compare_and_swap function for uint64]) +fi + dnl ***************** dnl ***** options ***** dnl ***************** diff --git a/lib/Makefile.am b/lib/Makefile.am index 2263252..1e8f02b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -15,7 +15,8 @@ lib_LTLIBRARIES = libtdata.la libtdata_la_SOURCES = \ avl.c lslist.c redblack.c splay.c \ - tree.c usrtc.c bitwise.c idx_allocator.c + tree.c usrtc.c bitwise.c idx_allocator.c \ + cas.c libtdata_la_LDFLAGS = diff --git a/lib/cas.c b/lib/cas.c new file mode 100644 index 0000000..3a35d7c --- /dev/null +++ b/lib/cas.c @@ -0,0 +1,51 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */ +/* + * cas.c + * Copyright (C) 2015 Alexander Vdolainen + * + * libtdata is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libtdata is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see ."; + */ + +#include +#include + +#include "../config.h" + +#if !defined (HAVE__SYNC_BOOL_COMPARE_AND_SWAP_8) +#include +static pthread_mutex_t __sync_lock = PTHREAD_MUTEX_INITIALIZER; +#endif + +#ifndef HAVE__SYNC_BOOL_COMPARE_AND_SWAP_8 +_Bool __sync_bool_compare_and_swap_8 (uint64_t*, uint64_t, uint64_t) +__attribute__ ((visibility ("hidden"))); + +_Bool __sync_bool_compare_and_swap_8 (uint64_t* ptr, uint64_t old, uint64_t new) +{ + int i; + _Bool ret; + + i = pthread_mutex_lock(&sync_lock); + + if(*ptr != old) ret = 0; + else { + *ptr = new; + ret = 1; + } + + i = pthread_mutex_unlock(&sync_lock); + + return ret; +} +#endif