]> granicus.if.org Git - json-c/commitdiff
Add a --enable-threading configure option, and only use the (slower) __sync_add_and_f...
authorEric Haszlakiewicz <erh+git@nimenees.com>
Mon, 4 Sep 2017 03:37:12 +0000 (23:37 -0400)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Mon, 4 Sep 2017 03:37:12 +0000 (23:37 -0400)
README.md
configure.ac
json_object.c

index 0e87cd5617a2f87c9b751ede89566858989ea4d1..bddcff7afb1e3b3f9efdeb3cf2d6525d0eaee522 100644 (file)
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ $ sh autogen.sh
 followed by
 
 ```sh
-$ ./configure
+$ ./configure  # --enable-threading
 $ make
 $ make install
 ```
@@ -56,6 +56,25 @@ To build and run the test programs:
 $ make check
 ```
 
+Building with partial threading support
+----------------------------------------
+
+Although json-c does not support fully multi-threaded access to
+object trees, it has some code to help make use in threaded programs
+a bit safer.  Currently, this is limited to using atomic operations for
+json_object_get() and json_object_put().
+
+Since this may have a performance impact, of at least 3x slower
+according to https://stackoverflow.com/a/11609063, it is disabled by
+default.  You may turn it on by adjusting your configure command with:
+   --enable-threading
+
+Separately, the default hash function used for object field keys,
+lh_char_hash, uses a compare-and-swap operation to ensure the randomly
+seed is only generated once.  Because this is a one-time operation, it
+is always compiled in when the compare-and-swap operation is available.
+
+
 Linking to `libjson-c`
 ----------------------
 
index e909cf22f858a7b5b7470782d938d4e90648ffc3..0ebf823213576ef47116e8479168a6417c97027d 100644 (file)
@@ -11,12 +11,26 @@ AC_PROG_MAKE_SET
 
 AC_CANONICAL_HOST
 
+AC_ARG_ENABLE(threading,
+ AS_HELP_STRING([--enable-threading],
+   [Enable code to support partly multi-threaded use]),
+[if test x$enableval = xyes; then
+  enable_threading=yes
+  AC_DEFINE(ENABLE_THREADING, 1, [Enable partial threading support])
+fi])
+
+if test "x$enable_threading" = "xyes"; then
+  AC_MSG_RESULT([Partial multi-threaded support enabled.])
+else
+  AC_MSG_RESULT([Multi-threaded support disabled. Use --enable-threading to enable.])
+fi
+
 AC_ARG_ENABLE(rdrand,
  AS_HELP_STRING([--enable-rdrand],
    [Enable RDRAND Hardware RNG Hash Seed generation on supported x86/x64 platforms.]),
 [if test x$enableval = xyes; then
   enable_rdrand=yes
-  AC_DEFINE(ENABLE_RDRAND, 1, [Enable RDRANR Hardware RNG Hash Seed])
+  AC_DEFINE(ENABLE_RDRAND, 1, [Enable RDRAND Hardware RNG Hash Seed])
 fi])
 
 if test "x$enable_rdrand" = "xyes"; then
index c09d61d14ac4283429f3bbeea7d06aef94197c29..fcda69fb7f17e3d71da9fc5dcb8a7920737fc620 100644 (file)
@@ -165,7 +165,7 @@ extern struct json_object* json_object_get(struct json_object *jso)
 {
        if (!jso) return jso;
 
-#ifdef HAVE_ATOMIC_BUILTINS
+#if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
        __sync_add_and_fetch(&jso->_ref_count, 1);
 #else
        ++jso->_ref_count;
@@ -178,7 +178,7 @@ int json_object_put(struct json_object *jso)
 {
        if(!jso) return 0;
 
-#ifdef HAVE_ATOMIC_BUILTINS
+#if defined(HAVE_ATOMIC_BUILTINS) && defined(ENABLE_THREADING)
        /* 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,
@@ -703,7 +703,7 @@ int json_object_set_int64(struct json_object *jso,int64_t new_value){
 
 /* json_object_double */
 
-#ifdef HAVE___THREAD
+#if defined(HAVE___THREAD) && defined(ENABLE_THREADING)
 // i.e. __thread or __declspec(thread)
 static SPEC___THREAD char *tls_serialization_float_format = NULL;
 #endif
@@ -713,7 +713,7 @@ int json_c_set_serialization_double_format(const char *double_format, int global
 {
        if (global_or_thread == JSON_C_OPTION_GLOBAL)
        {
-#ifdef HAVE___THREAD
+#if defined(HAVE___THREAD) && defined(ENABLE_THREADING)
                if (tls_serialization_float_format)
                {
                        free(tls_serialization_float_format);
@@ -726,7 +726,7 @@ int json_c_set_serialization_double_format(const char *double_format, int global
        }
        else if (global_or_thread == JSON_C_OPTION_THREAD)
        {
-#ifdef HAVE___THREAD
+#if defined(HAVE___THREAD) && defined(ENABLE_THREADING)
                if (tls_serialization_float_format)
                {
                        free(tls_serialization_float_format);
@@ -775,7 +775,7 @@ static int json_object_double_to_json_string_format(struct json_object* jso,
        {
                const char *std_format = "%.17g";
 
-#ifdef HAVE___THREAD
+#if defined(HAVE___THREAD) && defined(ENABLE_THREADING)
                if (tls_serialization_float_format)
                        std_format = tls_serialization_float_format;
                else