gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libmicrohttpd2] 10/12: Implemented and used counters based on atomic va


From: Admin
Subject: [libmicrohttpd2] 10/12: Implemented and used counters based on atomic variables
Date: Fri, 06 Jun 2025 16:01:18 +0200

This is an automated email from the git hooks/post-receive script.

karlson2k pushed a commit to branch master
in repository libmicrohttpd2.

commit f1579ec8008ba0ecd23fb15b50a5bd7c31914e0f
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
AuthorDate: Thu Jun 5 00:50:44 2025 +0200

    Implemented and used counters based on atomic variables
---
 configure.ac                    | 102 ++++++++++++++++++++++++++++++++++++++++
 src/incl_priv/mhd_sys_options.h |   2 +
 src/mhd2/mhd_atomic_counter.h   |  87 ++++++++++++++++++++++++++++++++--
 3 files changed, 188 insertions(+), 3 deletions(-)

diff --git a/configure.ac b/configure.ac
index e553f09..6bb7781 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1472,6 +1472,108 @@ AS_CASE([${mhd_cv_cc_kwd_fallthrough}],
 CFLAGS_ac="${save_CFLAGS_ac}"
 CFLAGS="${CFLAGS_ac} ${user_CFLAGS}"
 
+# Check for full support of atomic variables 
+AC_CACHE_CHECK([whether $CC supports atomic variables],
+  [mhd_cv_c_atomic_variables],
+  [
+    AC_COMPILE_IFELSE(
+      [
+        AC_LANG_SOURCE(
+          [[
+#include <stdatomic.h>
+
+#ifdef __STDC_NO_ATOMICS__
+#error __STDC_NO_ATOMICS__ is declared
+choke me now
+#endif
+
+int main(void)
+{
+  volatile _Atomic int atmc_var;
+  int natmc_var;
+
+  atomic_init(&atmc_var, 0);
+
+  if (0 == atomic_exchange_explicit(&atmc_var, 16, memory_order_relaxed))
+    atomic_store_explicit(&atmc_var, 7, memory_order_release);
+
+  natmc_var = atomic_fetch_add_explicit(&atmc_var, 15, memory_order_acq_rel);
+
+  natmc_var = atomic_fetch_sub_explicit(&atmc_var, natmc_var, 
memory_order_relaxed);
+
+  natmc_var = atomic_fetch_or_explicit(&atmc_var, natmc_var, 
memory_order_seq_cst);
+
+  natmc_var = atomic_fetch_and_explicit(&atmc_var, natmc_var, 
memory_order_relaxed);
+
+  natmc_var = atomic_fetch_xor_explicit(&atmc_var, natmc_var, 
memory_order_release);
+
+  return natmc_var + 1 - atomic_load_explicit(&atmc_var, memory_order_acquire);
+}
+          ]]
+        )
+      ],
+      [mhd_cv_c_atomic_variables="yes"],[mhd_cv_c_atomic_variables="no"]
+    )
+  ]
+)
+AS_VAR_IF([mhd_cv_c_atomic_variables],["yes"],
+  [
+    AC_DEFINE([MHD_SUPPORT_ATOMIC_VARIABLES],[1],[Define to 1 i][f atomic 
variables are fully supported])
+    AC_DEFINE([MHD_SUPPORT_ATOMIC_COUNTERS],[1],[Define to 1 i][f counter 
subset of atomic operations is supported])
+  ],
+  [
+    # Check for minimal atomic variables support
+    AC_CACHE_CHECK([whether $CC supports atomic counters],
+      [mhd_cv_c_atomic_counters],
+      [
+        AC_COMPILE_IFELSE(
+          [
+            AC_LANG_SOURCE(
+              [[
+#if defined(HAVE_STDDEF_H)
+#  include <stddef.h> /* size_t */
+#elif defined(HAVE_STDLIB_H)
+#  include <stdlib.h> /* should provide size_t */
+#else
+#  include <stdio.h> /* should provide size_t */
+#endif
+#ifdef HAVE_CRTDEFS_H
+#  include <crtdefs.h> /* W32-specific header */
+#endif
+
+#include <stdatomic.h>
+
+#ifdef __STDC_NO_ATOMICS__
+#error __STDC_NO_ATOMICS__ is declared
+choke me now
+#endif
+
+int main(void)
+{
+  volatile _Atomic size_t cntr;
+
+  atomic_init(&cntr, 0);
+
+  atomic_fetch_add_explicit(&cntr, 1, memory_order_relaxed);
+  atomic_fetch_sub_explicit(&cntr, 1, memory_order_release);
+
+  return
+    (0u == atomic_load_explicit(&cntr, memory_order_relaxed)) ?
+    0 : 2;
+}
+              ]]
+            )
+          ],
+          [mhd_cv_c_atomic_counters="yes"],[mhd_cv_c_atomic_counters="no"]
+        )
+      ]
+    )
+    AS_VAR_IF([mhd_cv_c_atomic_counters],["yes"],
+      [AC_DEFINE([MHD_SUPPORT_ATOMIC_COUNTERS],[1],[Define to 1 i][f counter 
subset of atomic operations is supported])]
+    )
+  ]
+)
+
 AC_CHECK_HEADERS([stdalign.h], [], [], [AC_INCLUDES_DEFAULT])
 AC_CACHE_CHECK([[for C11 'alignof()' support]], [[mhd_cv_c_alignof]],
   [AC_COMPILE_IFELSE(
diff --git a/src/incl_priv/mhd_sys_options.h b/src/incl_priv/mhd_sys_options.h
index d25ea88..fa80f19 100644
--- a/src/incl_priv/mhd_sys_options.h
+++ b/src/incl_priv/mhd_sys_options.h
@@ -554,6 +554,8 @@
 #  define MHD_NORETURN_ __attribute__((__noreturn__))
 #  undef mhd_FALLTHROUGH
 #  define mhd_FALLTHROUGH ((void) 0)
+#  undef _Atomic
+#  define _Atomic /* empty */
 #endif
 
 /* Avoid interference with third-party headers */
diff --git a/src/mhd2/mhd_atomic_counter.h b/src/mhd2/mhd_atomic_counter.h
index 9bcf0cd..2e1cde8 100644
--- a/src/mhd2/mhd_atomic_counter.h
+++ b/src/mhd2/mhd_atomic_counter.h
@@ -48,10 +48,18 @@
 
 #ifdef MHD_SUPPORT_THREADS
 
+#  if defined(MHD_SUPPORT_ATOMIC_COUNTERS) && !defined(__STDC_NO_ATOMICS__)
+
+/**
+ * Atomic operations are based native compiler support for atomics
+ */
+#    define mhd_ATOMIC_NATIVE 1
+#  else
 /**
  * Atomic operations are based on locks
  */
-#  define mhd_ATOMIC_BY_LOCKS 1
+#    define mhd_ATOMIC_BY_LOCKS 1
+#  endif
 
 #else  /* ! MHD_SUPPORT_THREADS */
 
@@ -61,8 +69,21 @@
 #  define mhd_ATOMIC_SINGLE_THREAD 1
 #endif /* ! MHD_SUPPORT_THREADS */
 
+#if defined(mhd_ATOMIC_NATIVE)
+#  include <stdatomic.h>
+
+/**
+ * The atomic counter
+ */
+struct mhd_AtomicCounter
+{
+  /**
+   * Counter value.
+   */
+  volatile _Atomic mhd_ATOMIC_COUNTER_TYPE count;
+};
 
-#if defined(mhd_ATOMIC_BY_LOCKS)
+#elif defined(mhd_ATOMIC_BY_LOCKS)
 #  include "mhd_locks.h"
 #  include "sys_bool_type.h"
 
@@ -98,7 +119,67 @@ struct mhd_AtomicCounter
 #endif /* mhd_ATOMIC_SINGLE_THREAD */
 
 
-#if defined(mhd_ATOMIC_BY_LOCKS)
+#if defined(mhd_ATOMIC_NATIVE)
+
+/**
+ * Initialise the counter to specified value.
+ * @param pcnt the pointer to the counter to initialise
+ * @param initial_value the initial value for the counter
+ * @return 'true' if succeed, "false' if failed
+ * @warning Must not be called for the counters that has been initialised
+ *          already.
+ */
+#  define mhd_atomic_counter_init(pcnt,initial_value) \
+    (atomic_init (&((pcnt)->count), (initial_value)), (! 0))
+
+/**
+ * Deinitialise the counter.
+ * @param pcnt the pointer to the counter to deinitialise
+ * @warning Must be called only for the counters that has been initialised.
+ */
+#  define mhd_atomic_counter_deinit(pcnt) ((void) 0)
+
+/**
+ * Atomically increment the value of the counter
+ * @param pcnt the pointer to the counter to increment
+ */
+#  define mhd_atomic_counter_inc(pcnt)               \
+  do { atomic_fetch_add_explicit(&((pcnt)->count), 1, \
+                                 memory_order_relaxed); } while (0)
+
+/**
+ * Atomically increment the value of the counter and return the result
+ * @param pcnt the pointer to the counter to increment
+ * @return the final/resulting counter value
+ */
+#  define mhd_atomic_counter_inc_get(pcnt) \
+    (atomic_fetch_add_explicit(&((pcnt)->count), 1, memory_order_relaxed) + 1)
+
+/**
+ * Atomically decrement the value of the counter and return the result
+ * @param pcnt the pointer to the counter to decrement
+ * @return the final/resulting counter value
+ */
+#  define mhd_atomic_counter_dec_get(pcnt) \
+    (atomic_fetch_sub_explicit(&((pcnt)->count), 1, memory_order_release) - 1)
+
+/**
+ * Atomically get the value of the counter
+ * @param pcnt the pointer to the counter to get
+ * @return the counter value
+ */
+#  define mhd_atomic_counter_get(pcnt) \
+    (atomic_load_explicit(&((pcnt)->count), memory_order_relaxed))
+
+/**
+ * Atomically increment the value of the counter and return the result.
+ * The value is allowed to overflow and get back to zero.
+ * @param pcnt the pointer to the counter to increment
+ * @return the final/resulting counter value
+ */
+#  define mhd_atomic_counter_inc_wrap_get(pcnt) \
+    mhd_atomic_counter_inc_get (pcnt)
+#elif defined(mhd_ATOMIC_BY_LOCKS)
 
 /**
  * Initialise the counter to specified value.

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]