AC_CHECK_DECLS([isinf], [], [], [[#include <math.h>]])
AC_CHECK_DECLS([_isnan], [], [], [[#include <float.h>]])
AC_CHECK_DECLS([_finite], [], [], [[#include <float.h>]])
+AC_MSG_CHECKING(for GCC atomic builtins)
+AC_LINK_IFELSE(
+[
+ AC_LANG_SOURCE([[
+ int main() {
+ volatile unsigned int val = 1;
+ /* Note: __sync_val_compare_and_swap isn't checked here
+ * because it's protected by __GCC_HAVE_SYNC_COMPARE_AND_SWAP_<n>,
+ * which is automatically defined by gcc.
+ */
+ __sync_add_and_fetch(&val, 1);
+ __sync_sub_and_fetch(&val, 1);
+ return 0;
+ }
+ ]])
+],
+[
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_ATOMIC_BUILTINS],[1],[Has atomic builtins])
+],
+[
+ AC_MSG_RESULT([no])
+ AC_MSG_WARN([json-c will be built without atomic refcounts because atomic builtins are missing])
+])
case "${host_os}" in
linux*)
{
if (!jso) return jso;
-#if defined __GNUC__
+#ifdef HAVE_ATOMIC_BUILTINS
__sync_add_and_fetch(&jso->_ref_count, 1);
#else
++jso->_ref_count;
{
if(!jso) return 0;
-#if defined __GNUC__
+#ifdef HAVE_ATOMIC_BUILTINS
+ /* Note: this only allow the refcount to remain correct
+ * when multiple threads are adjusting it. It is still an error
+ * for a thread to decrement the refcount if it doesn't "own" it,
+ * as that can result in the thread that loses the race to 0
+ * operating on an already-freed object.
+ */
if (__sync_sub_and_fetch(&jso->_ref_count, 1) > 0) return 0;
#else
if (--jso->_ref_count > 0) return 0;