libmicrohttpd2

HTTP server C library (MHD 2.x, alpha)
Log | Files | Refs | README | LICENSE

commit c9fc4213198b67c1c06fba04e4bb8eb0250e8235
parent b9c6050de5c03c55b7b1adb6626c01743abcea41
Author: Evgeny Grin (Karlson2k) <k2k@drgrin.dev>
Date:   Sat, 30 Aug 2025 18:24:19 +0200

Implemented macros for compiler hints

Diffstat:
Mconfigure.ac | 49+++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/mhd2/Makefile.am | 1+
Asrc/mhd2/mhd_predict.h | 199+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 249 insertions(+), 0 deletions(-)

diff --git a/configure.ac b/configure.ac @@ -3142,6 +3142,55 @@ AC_CACHE_CHECK([[whether __builtin_bswap64() is available]], ]) AS_IF([[test "x$mhd_cv_func___builtin_bswap64_avail" = "xyes"]], [AC_DEFINE([[MHD_HAVE___BUILTIN_BSWAP64]], [[1]], [Define to 1 if you have __builtin_bswap64() builtin function])]) + +AC_CACHE_CHECK([whether $CC supports __builtin_expect_with_probability()],[mhd_cv_cc___builtin_expect_with_probability_avail], + [ + AC_LINK_IFELSE( + [ + AC_LANG_SOURCE( + [[ +int main(int argc, char *argv[]) +{ + (void) argv; + if (__builtin_expect_with_probability(argc < 1, 0, 0.9999)) return 1; + return 0; +} + ]] + ) + ], + [[mhd_cv_cc___builtin_expect_with_probability_avail="yes"]], + [[mhd_cv_cc___builtin_expect_with_probability_avail="no"]] + ) + ] +) +AS_VAR_IF([mhd_cv_cc___builtin_expect_with_probability_avail],["yes"], + [AC_DEFINE([[MHD_HAVE___BUILTIN_EXPECT_WITH_PROBABILITY]], [[1]], [Define to 1 if compiler supports __builtin_expect_with_probability() builtin function])], + [ + AC_CACHE_CHECK([whether $CC supports __builtin_expect()],[mhd_cv_cc___builtin_expect_avail], + [ + AC_LINK_IFELSE( + [ + AC_LANG_SOURCE( + [[ +int main(int argc, char *argv[]) +{ + (void) argv; + if (__builtin_expect(argc < 1, 0)) return 1; + return 0; +} + ]] + ) + ], + [[mhd_cv_cc___builtin_expect_avail="yes"]], + [[mhd_cv_cc___builtin_expect_avail="no"]] + ) + ] + ) + AS_VAR_IF([mhd_cv_cc___builtin_expect_avail],["yes"], + [AC_DEFINE([[MHD_HAVE___BUILTIN_EXPECT]], [[1]], [Define to 1 if compiler supports __builtin_expect() builtin function])] + ) + ] +) AC_CHECK_PROG([HAVE_CURL_BINARY],[curl],[yes],[no]) AM_CONDITIONAL([HAVE_CURL_BINARY],[test "x$HAVE_CURL_BINARY" = "xyes"]) diff --git a/src/mhd2/Makefile.am b/src/mhd2/Makefile.am @@ -36,6 +36,7 @@ libmicrohttpd2_la_SOURCES = \ sys_w32_ver.h \ mhd_align.h mhd_bithelpers.h mhd_byteorder.h \ mhd_constexpr.h mhd_assert.h mhd_unreachable.h \ + mhd_predict.h \ mhd_cntnr_ptr.h mhd_arr_num_elems.h \ mhd_tristate.h mhd_status_code_int.h \ mhd_socket_type.h mhd_sockets_macros.h \ diff --git a/src/mhd2/mhd_predict.h b/src/mhd2/mhd_predict.h @@ -0,0 +1,199 @@ +/* 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) 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_predict.h + * @brief Macros that provide the compiler with hints about + * the anticipated outcomes of conditional expressions. + * @author Karlson2k (Evgeny Grin) + */ + +#ifndef MHD_PREDICT_H +#define MHD_PREDICT_H 1 + +#include "mhd_sys_options.h" + +/** + * @defgroup mhd2_predict Branch prediction hints + * + * Internal helpers to annotate most probable branch outcomes. + * + * @warning Misusing prediction (marking the uncommon path as common) can harm + * performance. Measuring before and after is highly recommended. + * + * @see MHD_NO_PREDICT_COND + * + * @{ + */ + + +/** + * @def MHD_NO_PREDICT_COND + * + * When defined, disables all prediction hints regardless of compiler + * support, turning the macros into plain boolean expressions. + * + * This can be useful for benchmarking or debugging to assess the impact of + * branch prediction hints on a given workload and compiler. + */ + +#ifdef MHD_NO_PREDICT_COND +# ifdef MHD_HAVE___BUILTIN_EXPECT_WITH_PROBABILITY +# undef MHD_HAVE___BUILTIN_EXPECT_WITH_PROBABILITY +# endif +# ifdef MHD_HAVE___BUILTIN_EXPECT +# undef MHD_HAVE___BUILTIN_EXPECT +# endif +#else +# ifdef __has_builtin +# if ! defined(MHD_HAVE___BUILTIN_EXPECT_WITH_PROBABILITY) && \ + __has_builtin (__builtin_expect_with_probability) +# define MHD_HAVE___BUILTIN_EXPECT_WITH_PROBABILITY 1 +# endif +# if ! defined(MHD_HAVE___BUILTIN_EXPECT) && __has_builtin (__builtin_expect) +# define MHD_HAVE___BUILTIN_EXPECT 1 +# endif +# endif +#endif + + +/* + * True/false primitives with direct probability specification + */ + +/** + * @def mhd_COND_PRED_TRUE_P(cond, prob) + * + * Hint that @p cond is expected to be true with probability @p prob. + * + * @param cond Boolean-like expression; evaluated exactly once. + * @param prob Anticipated probability in the range [0.0, 1.0]. + * Only compile-time constants; avoid 0.0 or 1.0. + * + * Expands to compiler-specific intrinsics when available; otherwise to + * a boolean normalisation of @p cond. + * + * @see mhd_COND_PRED_FALSE_P + */ + +/** + * @def mhd_COND_PRED_FALSE_P(cond, prob) + * + * Hint that @p cond is expected to be false with probability @p prob. + * + * @param cond Boolean-like expression; evaluated exactly once. + * @param prob Anticipated probability in the range [0.0, 1.0]. + * Only compile-time constants; avoid 0.0 or 1.0. + * + * Expands to compiler-specific intrinsics when available; otherwise to + * a boolean normalisation of @p cond. + * + * @see mhd_COND_PRED_TRUE_P + */ + + +#if defined(MHD_HAVE___BUILTIN_EXPECT_WITH_PROBABILITY) +# define mhd_COND_PRED_TRUE_P(cond,prob) \ + __builtin_expect_with_probability (! ! (cond), ! 0, (prob)) +# define mhd_COND_PRED_FALSE_P(cond,prob) \ + __builtin_expect_with_probability (! ! (cond), 0, (prob)) +#elif defined(MHD_HAVE___BUILTIN_EXPECT) +# define mhd_COND_PRED_TRUE_P(cond,prob) __builtin_expect (! ! (cond), ! 0) +# define mhd_COND_PRED_FALSE_P(cond,prob) __builtin_expect (! ! (cond), 0) +#else +# define mhd_COND_PRED_TRUE_P(cond,prob) (! ! (cond)) +# define mhd_COND_PRED_FALSE_P(cond,prob) (! ! (cond)) +#endif + +/* + * Implementation notes: + * - The double negation (!!) normalises any non-zero to 1 and keeps 0 as 0, + * ensuring the 'expected' value matches the intrinsic's contract. + * - The literal '!0' expresses boolean true without implying an integer + * width. + */ + + +/* + * Readable convenience wrappers + */ + +/** + * Hint: @p cond is true ~99.999% of the time. + * + * Useful for conditions whose failure indicates exceptional or defensive + * paths that almost never triggered in normal operation. + */ +#define mhd_COND_VIRTUALLY_ALWAYS(cond) mhd_COND_PRED_TRUE_P ((cond), 0.99999) +/** + * Hint: @p cond is true ~99% of the time. + */ +#define mhd_COND_ALMOST_ALWAYS(cond) mhd_COND_PRED_TRUE_P ((cond), 0.99) +/** + * Hint: @p cond is true ~95% of the time. + */ +#define mhd_COND_PREDOMINANTLY(cond) mhd_COND_PRED_TRUE_P ((cond), 0.95) +/** + * Hint: @p cond is true ~90% of the time. + */ +#define mhd_COND_USUALLY(cond) mhd_COND_PRED_TRUE_P ((cond), 0.9) + +/** + * Hint: @p cond is false ~90% of the time (i.e., the true branch is rare). + */ +#define mhd_COND_RARELY(cond) mhd_COND_PRED_FALSE_P ((cond), 0.9) +/** + * Hint: @p cond is false ~95% of the time (i.e., the true branch is very rare). + */ +#define mhd_COND_VERY_RARELY(cond) mhd_COND_PRED_FALSE_P ((cond), 0.95) +/** + * Hint: @p cond is false ~99% of the time (i.e., the true branch almost never + * triggers). + */ +#define mhd_COND_ALMOST_NEVER(cond) mhd_COND_PRED_FALSE_P ((cond), 0.99) +/** + * Hint: @p cond is false ~99.999% of the time. + * + * Useful for conditions whose truth indicates exceptional or defensive + * paths that almost never triggered in normal operation. + */ +#define mhd_COND_HARDLY_EVER(cond) mhd_COND_PRED_FALSE_P ((cond), 0.99999) + +/** @} */ /* end of mhd2_predict group */ + +#endif /* ! MHD_PREDICT_H */