commit 0fe26531aeb3c5900392eaf5adc3c03ce6f9fe7b
parent 7919626fb37cfcf57e5fa75f9c6835a13c610473
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date: Mon, 10 Aug 2026 17:54:08 +0200
mhd_atomic_counter: corrected, migrated to header-only
Diffstat:
4 files changed, 103 insertions(+), 200 deletions(-)
diff --git a/configure.ac b/configure.ac
@@ -1948,7 +1948,9 @@ int main(void)
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);
+ atomic_thread_fence (memory_order_acquire);
+
+ return natmc_var + 1 - atomic_load_explicit(&atmc_var, memory_order_relaxed);
}
]]
)
@@ -1984,11 +1986,6 @@ AS_VAR_IF([mhd_cv_c_atomic_variables],["yes"],
#include <stdatomic.h>
-#ifdef __STDC_NO_ATOMICS__
-#error __STDC_NO_ATOMICS__ is declared
-fail test here %%%@<:@-1@:>@
-#endif
-
int main(void)
{
volatile _Atomic size_t cntr;
@@ -1997,6 +1994,7 @@ int main(void)
atomic_fetch_add_explicit(&cntr, 1, memory_order_relaxed);
atomic_fetch_sub_explicit(&cntr, 1, memory_order_release);
+ atomic_thread_fence (memory_order_acquire);
return
(0u == atomic_load_explicit(&cntr, memory_order_relaxed)) ?
diff --git a/src/mhd2/Makefile.am b/src/mhd2/Makefile.am
@@ -42,7 +42,7 @@ libmicrohttpd2_la_SOURCES = \
mhd_socket_type.h mhd_sockets_macros.h \
mhd_sockets_funcs.c mhd_sockets_funcs.h \
mhd_socket_error_funcs.c mhd_socket_error_funcs.h mhd_socket_error.h \
- mhd_atomic_counter.c mhd_atomic_counter.h \
+ mhd_atomic_counter.h \
mhd_bool.h \
mhd_str.c mhd_str.h \
mhd_rng.c mhd_rng.h \
diff --git a/src/mhd2/mhd_atomic_counter.c b/src/mhd2/mhd_atomic_counter.c
@@ -1,110 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later OR (GPL-2.0-or-later WITH eCos-exception-2.0) */
-/*
- This file is part of GNU libmicrohttpd.
- Copyright (C) 2024-2025 Evgeny Grin (Karlson2k)
-
- GNU libmicrohttpd 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 2.1 of the License, or (at your option) any later version.
-
- GNU libmicrohttpd 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.
-
- Alternatively, you can redistribute GNU libmicrohttpd and/or
- modify it under the terms of the GNU General Public License as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version, together
- with the eCos exception, as follows:
-
- As a special exception, if other files instantiate templates or
- use macros or inline functions from this file, or you compile this
- file and link it with other works to produce a work based on this
- file, this file does not by itself cause the resulting work to be
- covered by the GNU General Public License. However the source code
- for this file must still be made available in accordance with
- section (3) of the GNU General Public License v2.
-
- This exception does not invalidate any other reasons why a work
- based on this file might be covered by the GNU General Public
- License.
-
- You should have received copies of the GNU Lesser General Public
- License and the GNU General Public License along with this library;
- if not, see <https://www.gnu.org/licenses/>.
-*/
-
-/**
- * @file src/mhd2/mhd_atomic_counter.c
- * @brief The definition of the atomic counter functions
- * @author Karlson2k (Evgeny Grin)
- */
-
-#include "mhd_sys_options.h"
-
-#include "mhd_atomic_counter.h"
-
-#if defined(mhd_ATOMIC_BY_LOCKS)
-
-# include "mhd_assert.h"
-
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt)
-{
- mhd_ATOMIC_COUNTER_TYPE ret;
-
- mhd_mutex_lock_chk (&(pcnt->lock));
- ret = pcnt->count++;
- mhd_mutex_unlock_chk (&(pcnt->lock));
-
- return ret;
-}
-
-
-# ifndef NDEBUG
-
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt)
-{
- const mhd_ATOMIC_COUNTER_TYPE ret = mhd_atomic_counter_get_inc_wrap (pcnt);
-
- mhd_assert (mhd_ATOMIC_COUNTER_MAX != ret); /* check for overflow */
-
- return ret;
-}
-
-
-# endif /* ! NDEBUG */
-
-
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt)
-{
- mhd_ATOMIC_COUNTER_TYPE ret;
-
- mhd_mutex_lock_chk (&(pcnt->lock));
- ret = pcnt->count--;
- mhd_mutex_unlock_chk (&(pcnt->lock));
-
- mhd_assert (mhd_ATOMIC_COUNTER_MAX != ret); /* check for underflow */
-
- return ret;
-}
-
-
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt)
-{
- mhd_ATOMIC_COUNTER_TYPE ret;
-
- mhd_mutex_lock_chk (&(pcnt->lock));
- ret = pcnt->count;
- mhd_mutex_unlock_chk (&(pcnt->lock));
-
- return ret;
-}
-
-
-#endif /* mhd_ATOMIC_BY_LOCKS */
diff --git a/src/mhd2/mhd_atomic_counter.h b/src/mhd2/mhd_atomic_counter.h
@@ -137,6 +137,11 @@ struct mhd_AtomicCounter
#endif /* mhd_ATOMIC_SINGLE_THREAD */
+#if defined(_MSC_FULL_VER)
+# pragma warning(push)
+/* Disable C4505 "unreferenced local function has been removed" */
+# pragma warning(disable:4505)
+#endif /* _MSC_FULL_VER */
#if defined(mhd_ATOMIC_NATIVE)
@@ -166,48 +171,25 @@ struct mhd_AtomicCounter
*/
# define mhd_atomic_counter_get_inc_wrap(pcnt) \
atomic_fetch_add_explicit (&((pcnt)->count), \
- 1, memory_order_relaxed)
+ 1u, memory_order_relaxed)
-# ifdef NDEBUG
/**
* Atomically increment the value of the counter.
* Counter overflow is detected in debug builds.
* @param pcnt the pointer to the counter to increment
*/
-# define mhd_atomic_counter_inc(pcnt) \
- do { (void) \
- atomic_fetch_add_explicit (&((pcnt)->count), 1, \
+# ifdef NDEBUG
+# define mhd_atomic_counter_inc(pcnt) \
+ do { (void) \
+ atomic_fetch_add_explicit (&((pcnt)->count), 1u, \
memory_order_relaxed); } while (0)
-
-/**
- * Get the value of the counter and atomically increment the counter.
- * Counter overflow is detected in debug builds.
- * @param pcnt the pointer to the counter to increment
- * @return the counter value before the increment
- */
-# define mhd_atomic_counter_get_inc(pcnt) \
- mhd_atomic_counter_get_inc_wrap ((pcnt))
-
-/**
- * Get the value of the counter and atomically decrement the counter.
- * Counter underflow is detected in debug builds.
- * @param pcnt the pointer to the counter to decrement
- * @return the counter value before the decrement
- */
-# define mhd_atomic_counter_get_dec(pcnt) \
- atomic_fetch_sub_explicit (&((pcnt)->count), \
- 1, memory_order_release)
# else /* _DEBUG */
-/**
- * Atomically increment the value of the counter.
- * Counter overflow is detected in debug builds.
- * @param pcnt the pointer to the counter to increment
- */
-# define mhd_atomic_counter_inc(pcnt) \
+# define mhd_atomic_counter_inc(pcnt) \
do { mhd_ATOMIC_COUNTER_TYPE old_val = \
- atomic_fetch_add_explicit (&((pcnt)->count), 1, \
+ atomic_fetch_add_explicit (&((pcnt)->count), 1u, \
memory_order_relaxed); \
mhd_assert (mhd_ATOMIC_COUNTER_MAX != old_val); } while (0)
+# endif /* _DEBUG */
/**
* Get the value of the counter and atomically increment the counter.
@@ -215,7 +197,11 @@ struct mhd_AtomicCounter
* @param pcnt the pointer to the counter to increment
* @return the counter value before the increment
*/
-mhd_static_inline mhd_ATOMIC_COUNTER_TYPE
+# ifdef NDEBUG
+# define mhd_atomic_counter_get_inc(pcnt) \
+ mhd_atomic_counter_get_inc_wrap ((pcnt))
+# else /* _DEBUG */
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt)
{
mhd_ATOMIC_COUNTER_TYPE ret;
@@ -228,27 +214,31 @@ mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt)
}
+# endif /* _DEBUG */
+
/**
* Get the value of the counter and atomically decrement the counter.
* Counter underflow is detected in debug builds.
* @param pcnt the pointer to the counter to decrement
* @return the counter value before the decrement
*/
-mhd_static_inline mhd_ATOMIC_COUNTER_TYPE
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt)
{
mhd_ATOMIC_COUNTER_TYPE ret;
- ret = atomic_fetch_sub_explicit (&((pcnt)->count), 1, memory_order_relaxed);
+ ret = atomic_fetch_sub_explicit (&((pcnt)->count),
+ 1u,
+ memory_order_release);
+ if (1u == ret) /* Sync with preceding releases when the last reference is dropped */
+ atomic_thread_fence (memory_order_acquire);
- mhd_assert (0 != ret);
+ mhd_assert (0u != ret);
return ret;
}
-# endif /* _DEBUG */
-
/**
* Atomically get the value of the counter.
* @param pcnt the pointer to the counter to get
@@ -284,43 +274,37 @@ mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt)
* @param pcnt the pointer to the counter to increment
* @return the counter value before the increment
*/
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt);
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
+mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt)
+{
+ mhd_ATOMIC_COUNTER_TYPE ret;
+
+ mhd_mutex_lock_chk (&(pcnt->lock));
+ ret = pcnt->count++;
+ mhd_mutex_unlock_chk (&(pcnt->lock));
+
+ return ret;
+}
-# ifdef NDEBUG
/**
* Atomically increment the value of the counter.
* Counter overflow is detected in debug builds.
* @param pcnt the pointer to the counter to increment
*/
+# ifdef NDEBUG
# define mhd_atomic_counter_inc(pcnt) do { \
mhd_mutex_lock_chk (&((pcnt)->lock)); \
++((pcnt)->count); \
mhd_mutex_unlock_chk (&((pcnt)->lock)); } while (0)
-
-/**
- * Get the value of the counter and atomically increment the counter.
- * Counter overflow is detected in debug builds.
- * @param pcnt the pointer to the counter to increment
- * @return the counter value before the increment
- */
-# define mhd_atomic_counter_get_inc(pcnt) \
- mhd_atomic_counter_get_inc_wrap (pcnt)
-
-# else
-
-/**
- * Atomically increment the value of the counter.
- * Counter overflow is detected in debug builds.
- * @param pcnt the pointer to the counter to increment
- */
+# else /* _DEBUG */
# define mhd_atomic_counter_inc(pcnt) do {\
mhd_ATOMIC_COUNTER_TYPE old_val; \
mhd_mutex_lock_chk (&((pcnt)->lock)); \
old_val = (pcnt)->count++; \
mhd_mutex_unlock_chk (&((pcnt)->lock)); \
mhd_assert (mhd_ATOMIC_COUNTER_MAX != old_val); } while (0)
+# endif /* _DEBUG */
/**
* Get the value of the counter and atomically increment the counter.
@@ -328,10 +312,23 @@ mhd_atomic_counter_get_inc_wrap (struct mhd_AtomicCounter *pcnt);
* @param pcnt the pointer to the counter to increment
* @return the counter value before the increment
*/
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt);
+# ifdef NDEBUG
+# define mhd_atomic_counter_get_inc(pcnt) \
+ mhd_atomic_counter_get_inc_wrap ((pcnt))
+
+# else /* _DEBUG */
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
+mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt)
+{
+ const mhd_ATOMIC_COUNTER_TYPE ret = mhd_atomic_counter_get_inc_wrap (pcnt);
+
+ mhd_assert (mhd_ATOMIC_COUNTER_MAX != ret); /* check for overflow */
+
+ return ret;
+}
-# endif
+
+# endif /* _DEBUG */
/**
* Get the value of the counter and atomically decrement the counter.
@@ -339,16 +336,38 @@ mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt);
* @param pcnt the pointer to the counter to decrement
* @return the counter value before the decrement
*/
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt);
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
+mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt)
+{
+ mhd_ATOMIC_COUNTER_TYPE ret;
+
+ mhd_mutex_lock_chk (&(pcnt->lock));
+ ret = pcnt->count--;
+ mhd_mutex_unlock_chk (&(pcnt->lock));
+
+ mhd_assert (0u != ret); /* check for underflow */
+
+ return ret;
+}
+
/**
* Atomically get the value of the counter.
* @param pcnt the pointer to the counter to get
* @return the counter value
*/
-MHD_INTERNAL mhd_ATOMIC_COUNTER_TYPE
-mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt);
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
+mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt)
+{
+ mhd_ATOMIC_COUNTER_TYPE ret;
+
+ mhd_mutex_lock_chk (&(pcnt->lock));
+ ret = pcnt->count;
+ mhd_mutex_unlock_chk (&(pcnt->lock));
+
+ return ret;
+}
+
#elif defined(mhd_ATOMIC_SINGLE_THREAD)
@@ -387,32 +406,17 @@ mhd_atomic_counter_get (struct mhd_AtomicCounter *pcnt);
do { mhd_assert (mhd_ATOMIC_COUNTER_MAX != ((pcnt)->count)); \
++((pcnt)->count); } while (0)
-# ifdef NDEBUG
/**
* Get the value of the counter and atomically increment the counter.
* Counter overflow is detected in debug builds.
* @param pcnt the pointer to the counter to increment
* @return the counter value before the increment
*/
+# ifdef NDEBUG
# define mhd_atomic_counter_get_inc(pcnt) \
mhd_atomic_counter_get_inc_wrap ((pcnt))
-
-/**
- * Get the value of the counter and atomically decrement the counter.
- * Counter underflow is detected in debug builds.
- * @param pcnt the pointer to the counter to decrement
- * @return the counter value before the decrement
- */
-# define mhd_atomic_counter_get_dec(pcnt) ((pcnt)->count--)
-
# else /* _DEBUG */
-/**
- * Get the value of the counter and atomically increment the counter.
- * Counter overflow is detected in debug builds.
- * @param pcnt the pointer to the counter to increment
- * @return the counter value before the increment
- */
-mhd_static_inline mhd_ATOMIC_COUNTER_TYPE
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt)
{
mhd_assert (mhd_ATOMIC_COUNTER_MAX != (pcnt->count));
@@ -421,16 +425,21 @@ mhd_atomic_counter_get_inc (struct mhd_AtomicCounter *pcnt)
}
+# endif /* _DEBUG */
+
/**
* Get the value of the counter and atomically decrement the counter.
* Counter underflow is detected in debug builds.
* @param pcnt the pointer to the counter to decrement
* @return the counter value before the decrement
*/
-mhd_static_inline mhd_ATOMIC_COUNTER_TYPE
+# ifdef NDEBUG
+# define mhd_atomic_counter_get_dec(pcnt) ((pcnt)->count--)
+# else /* _DEBUG */
+mhd_static_inline MHD_FN_PAR_NONNULL_ALL_ mhd_ATOMIC_COUNTER_TYPE
mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt)
{
- mhd_assert (0 != ((pcnt)->count));
+ mhd_assert (0u != ((pcnt)->count));
return ((pcnt)->count--);
}
@@ -447,4 +456,10 @@ mhd_atomic_counter_get_dec (struct mhd_AtomicCounter *pcnt)
#endif /* mhd_ATOMIC_SINGLE_THREAD */
+
+#if defined(_MSC_FULL_VER)
+/* Restore warnings */
+# pragma warning(pop)
+#endif /* _MSC_FULL_VER */
+
#endif /* ! MHD_ATOMIC_COUNTER_H */