mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
sync
This commit is contained in:
parent
91ce2ab459
commit
e0f5b65442
180
configure
vendored
180
configure
vendored
|
@ -915,10 +915,10 @@ MINGW_FALSE
|
|||
MINGW_TRUE
|
||||
LINUX_FALSE
|
||||
LINUX_TRUE
|
||||
CLANG_FALSE
|
||||
CLANG_TRUE
|
||||
INTEL_FALSE
|
||||
INTEL_TRUE
|
||||
CLANG_FALSE
|
||||
CLANG_TRUE
|
||||
LN_S
|
||||
am__fastdepCXX_FALSE
|
||||
am__fastdepCXX_TRUE
|
||||
|
@ -7586,85 +7586,37 @@ _ACEOF
|
|||
esac
|
||||
|
||||
|
||||
# clang is mostly GCC-compatible, but its version is much lower, so we have to check for it
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiling with Intel C++" >&5
|
||||
$as_echo_n "checking if compiling with Intel C++... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiling with GNU C++" >&5
|
||||
$as_echo_n "checking if compiling with GNU C++... " >&6; }
|
||||
GCC_COMPILER=$($CXX --version 2>/dev/null | grep -v -E '(llvm|clang)' | grep -i -c -E '(gcc|g\+\+)')
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
#ifndef __INTEL_COMPILER
|
||||
not intel
|
||||
#endif
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
GCC_IS_INTEL=yes
|
||||
GCC_IS_GNU=no
|
||||
if [ "$GCC_COMPILER" -eq 0 ]; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
GCC_IS_INTEL=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
GCC_IS_GNU=yes
|
||||
gcc_version=`gcc -dumpversion`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($gcc_version)" >&5
|
||||
$as_echo "yes ($gcc_version)" >&6; }
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCC_IS_INTEL" >&5
|
||||
$as_echo "$GCC_IS_INTEL" >&6; }
|
||||
#AC_SUBST(GCC_IS_INTEL)
|
||||
$as_echo "#define GCC_IS_GNU 1" >>confdefs.h
|
||||
|
||||
if false; then
|
||||
INTEL_TRUE=
|
||||
INTEL_FALSE='#'
|
||||
else
|
||||
INTEL_TRUE='#'
|
||||
INTEL_FALSE=
|
||||
fi
|
||||
|
||||
if test "$GCC_IS_INTEL" = "yes"; then
|
||||
if true; then
|
||||
INTEL_TRUE=
|
||||
INTEL_FALSE='#'
|
||||
else
|
||||
INTEL_TRUE='#'
|
||||
INTEL_FALSE=
|
||||
fi
|
||||
|
||||
gcc_version=`icc -dumpversion`
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiling with clang" >&5
|
||||
$as_echo_n "checking if compiling with clang... " >&6; }
|
||||
CLANG_COMPILER=$($CXX --version 2>/dev/null | grep -i -c -E '(llvm|clang)')
|
||||
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
#ifndef __clang__
|
||||
not clang
|
||||
#endif
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_compile "$LINENO"; then :
|
||||
GCC_IS_CLANG=yes
|
||||
else
|
||||
GCC_IS_CLANG=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCC_IS_CLANG" >&5
|
||||
$as_echo "$GCC_IS_CLANG" >&6; }
|
||||
#AC_SUBST(GCC_IS_CLANG)
|
||||
# AC_COMPILE_IFELSE(
|
||||
# [AC_LANG_PROGRAM([], [[
|
||||
# #ifndef __clang__
|
||||
# not clang
|
||||
# #endif
|
||||
# ]])],
|
||||
# [GCC_IS_CLANG=yes], [GCC_IS_CLANG=no])
|
||||
|
||||
GCC_IS_CLANG=no
|
||||
if false; then
|
||||
CLANG_TRUE=
|
||||
CLANG_FALSE='#'
|
||||
|
@ -7673,8 +7625,12 @@ else
|
|||
CLANG_FALSE=
|
||||
fi
|
||||
|
||||
if test "$GCC_IS_CLANG" = "yes"; then
|
||||
if true; then
|
||||
if [ "$CLANG_COMPILER" -eq 0 ]; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
GCC_IS_CLANG=yes
|
||||
if true; then
|
||||
CLANG_TRUE=
|
||||
CLANG_FALSE='#'
|
||||
else
|
||||
|
@ -7682,9 +7638,54 @@ else
|
|||
CLANG_FALSE=
|
||||
fi
|
||||
|
||||
gcc_version=`clang -dumpversion`
|
||||
gcc_version=`clang -dumpversion`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($gcc_version)" >&5
|
||||
$as_echo "yes ($gcc_version)" >&6; }
|
||||
fi
|
||||
|
||||
#AC_SUBST(GCC_IS_CLANG)
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiling with Intel C++" >&5
|
||||
$as_echo_n "checking if compiling with Intel C++... " >&6; }
|
||||
INTEL_COMPILER=$($CXX --version 2>/dev/null | grep -i -c '\(icc\)')
|
||||
|
||||
# AC_COMPILE_IFELSE(
|
||||
# [AC_LANG_PROGRAM([], [[
|
||||
# #ifndef __INTEL_COMPILER
|
||||
# not intel
|
||||
# #endif
|
||||
# ]])],
|
||||
# [GCC_IS_INTEL=yes], [GCC_IS_INTEL=no])
|
||||
|
||||
GCC_IS_INTEL=no
|
||||
if false; then
|
||||
INTEL_TRUE=
|
||||
INTEL_FALSE='#'
|
||||
else
|
||||
INTEL_TRUE='#'
|
||||
INTEL_FALSE=
|
||||
fi
|
||||
|
||||
if [ "$INTEL_COMPILER" -eq 0 ]; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
else
|
||||
GCC_IS_INTEL=yes
|
||||
if true; then
|
||||
INTEL_TRUE=
|
||||
INTEL_FALSE='#'
|
||||
else
|
||||
INTEL_TRUE='#'
|
||||
INTEL_FALSE=
|
||||
fi
|
||||
|
||||
gcc_version=`icc -dumpversion`
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes ($gcc_version)" >&5
|
||||
$as_echo "yes ($gcc_version)" >&6; }
|
||||
fi
|
||||
|
||||
#AC_SUBST(GCC_IS_INTEL)
|
||||
|
||||
ULIB_LIBS=
|
||||
MODULE_LIBTOOL_OPTIONS="-shared -export-dynamic -avoid-version"
|
||||
|
||||
|
@ -8610,11 +8611,10 @@ fi
|
|||
|
||||
# Check for the compiler support
|
||||
gcc_major_4_1="no"
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes" -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
# We don't want gcc 2.7
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a supported version of gcc" >&5
|
||||
$as_echo_n "checking for a supported version of gcc... " >&6; }
|
||||
gcc_version=`$CC -dumpversion`
|
||||
case "$gcc_version" in
|
||||
1.*|2.7.*|2.8.*)
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no ($gcc_version)" >&5
|
||||
|
@ -21779,7 +21779,7 @@ else
|
|||
STDCPP_FALSE=
|
||||
fi
|
||||
|
||||
if test x"$GCC" = "xyes" ; then
|
||||
if test "x$GCC_IS_GNU" = xyes ; then
|
||||
lcflags="-nodefaultlibs -nostdinc++"
|
||||
else
|
||||
lcflags="-library=no%Cstd -features=no%except -features=no%rtti"
|
||||
|
@ -32714,7 +32714,7 @@ fi
|
|||
|
||||
# If gcc compiler add values to *FLAGS...
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes" -a "x$OPERATINGSYSTEM" = xlinux; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "x$OPERATINGSYSTEM" = xlinux; then
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: " >&5
|
||||
|
@ -33258,9 +33258,9 @@ fi
|
|||
case "$target_os" in
|
||||
*bsd*)
|
||||
if test "$enable_stdcpp" != "yes"; then
|
||||
if test "$GCC" = "yes" -a "$ULIB_LIBC" = "-lc" ; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "$ULIB_LIBC" = "-lc" ; then
|
||||
ULIB_LIBC="-Wl,-lc"
|
||||
elif test "$GCC" = "yes" -a "$ULIB_LIBC" = "-lc_r" ; then
|
||||
elif test "x$GCC_IS_GNU" = xyes -a "$ULIB_LIBC" = "-lc_r" ; then
|
||||
ULIB_LIBC="-Wl,-lc_r"
|
||||
fi
|
||||
fi
|
||||
|
@ -33541,7 +33541,7 @@ if test "x$ac_cv_crc32_intrinsics" = xyes; then
|
|||
fi
|
||||
##########################
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes" -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
if test "$enable_static" = "yes" -a "$enable_shared" = "no" -a "$enable_stdcpp" = "yes"; then
|
||||
|
||||
## if test -f "$gcc_dir/libstdc++.a"; then
|
||||
|
@ -33797,7 +33797,7 @@ $as_echo "${T_MD}Output Substitution:${T_ME}" >&6; }
|
|||
|
||||
|
||||
# Create compiler version string
|
||||
if test x"$GCC" = x"yes" ; then
|
||||
if test "x$GCC_IS_GNU" = xyes ; then
|
||||
cc_string=`${CC} --version | sed q`
|
||||
case $cc_string in [A-Za-z]*) ;; *) cc_string="GCC $cc_string";; esac
|
||||
elif test x"$SUN_STUDIO_CC" = x"yes" ; then
|
||||
|
@ -34273,14 +34273,6 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
|
|||
as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${INTEL_TRUE}" && test -z "${INTEL_FALSE}"; then
|
||||
as_fn_error $? "conditional \"INTEL\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${INTEL_TRUE}" && test -z "${INTEL_FALSE}"; then
|
||||
as_fn_error $? "conditional \"INTEL\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${CLANG_TRUE}" && test -z "${CLANG_FALSE}"; then
|
||||
as_fn_error $? "conditional \"CLANG\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
|
@ -34289,6 +34281,14 @@ if test -z "${CLANG_TRUE}" && test -z "${CLANG_FALSE}"; then
|
|||
as_fn_error $? "conditional \"CLANG\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${INTEL_TRUE}" && test -z "${INTEL_FALSE}"; then
|
||||
as_fn_error $? "conditional \"INTEL\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${INTEL_TRUE}" && test -z "${INTEL_FALSE}"; then
|
||||
as_fn_error $? "conditional \"INTEL\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
fi
|
||||
if test -z "${LINUX_TRUE}" && test -z "${LINUX_FALSE}"; then
|
||||
as_fn_error $? "conditional \"LINUX\" was never defined.
|
||||
Usually this means the macro was only invoked conditionally." "$LINENO" 5
|
||||
|
|
95
configure.ac
95
configure.ac
|
@ -279,45 +279,67 @@ AC_C_RESTRICT
|
|||
AC_C_VOLATILE
|
||||
AC_C_INLINE
|
||||
|
||||
# clang is mostly GCC-compatible, but its version is much lower, so we have to check for it
|
||||
AC_MSG_CHECKING([if compiling with Intel C++])
|
||||
AC_MSG_CHECKING([if compiling with GNU C++])
|
||||
GCC_COMPILER=$($CXX --version 2>/dev/null | grep -v -E '(llvm|clang)' | grep -i -c -E '(gcc|g\+\+)')
|
||||
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([], [[
|
||||
#ifndef __INTEL_COMPILER
|
||||
not intel
|
||||
#endif
|
||||
]])],
|
||||
[GCC_IS_INTEL=yes], [GCC_IS_INTEL=no])
|
||||
|
||||
AC_MSG_RESULT([$GCC_IS_INTEL])
|
||||
#AC_SUBST(GCC_IS_INTEL)
|
||||
|
||||
AM_CONDITIONAL(INTEL, false)
|
||||
if test "$GCC_IS_INTEL" = "yes"; then
|
||||
AM_CONDITIONAL(INTEL, true)
|
||||
gcc_version=`icc -dumpversion`
|
||||
GCC_IS_GNU=no
|
||||
if [[ "$GCC_COMPILER" -eq 0 ]]; then
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
GCC_IS_GNU=yes
|
||||
gcc_version=`gcc -dumpversion`
|
||||
AC_MSG_RESULT([yes ($gcc_version)])
|
||||
AC_DEFINE([GCC_IS_GNU],[1],[Define if we are using gcc compiler])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING([if compiling with clang])
|
||||
CLANG_COMPILER=$($CXX --version 2>/dev/null | grep -i -c -E '(llvm|clang)')
|
||||
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([], [[
|
||||
#ifndef __clang__
|
||||
not clang
|
||||
#endif
|
||||
]])],
|
||||
[GCC_IS_CLANG=yes], [GCC_IS_CLANG=no])
|
||||
# AC_COMPILE_IFELSE(
|
||||
# [AC_LANG_PROGRAM([], [[
|
||||
# #ifndef __clang__
|
||||
# not clang
|
||||
# #endif
|
||||
# ]])],
|
||||
# [GCC_IS_CLANG=yes], [GCC_IS_CLANG=no])
|
||||
|
||||
GCC_IS_CLANG=no
|
||||
AM_CONDITIONAL(CLANG, false)
|
||||
if [[ "$CLANG_COMPILER" -eq 0 ]]; then
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
GCC_IS_CLANG=yes
|
||||
AM_CONDITIONAL(CLANG, true)
|
||||
gcc_version=`clang -dumpversion`
|
||||
AC_MSG_RESULT([yes ($gcc_version)])
|
||||
fi
|
||||
|
||||
AC_MSG_RESULT([$GCC_IS_CLANG])
|
||||
#AC_SUBST(GCC_IS_CLANG)
|
||||
|
||||
AM_CONDITIONAL(CLANG, false)
|
||||
if test "$GCC_IS_CLANG" = "yes"; then
|
||||
AM_CONDITIONAL(CLANG, true)
|
||||
gcc_version=`clang -dumpversion`
|
||||
AC_MSG_CHECKING([if compiling with Intel C++])
|
||||
INTEL_COMPILER=$($CXX --version 2>/dev/null | grep -i -c '\(icc\)')
|
||||
|
||||
# AC_COMPILE_IFELSE(
|
||||
# [AC_LANG_PROGRAM([], [[
|
||||
# #ifndef __INTEL_COMPILER
|
||||
# not intel
|
||||
# #endif
|
||||
# ]])],
|
||||
# [GCC_IS_INTEL=yes], [GCC_IS_INTEL=no])
|
||||
|
||||
GCC_IS_INTEL=no
|
||||
AM_CONDITIONAL(INTEL, false)
|
||||
if [[ "$INTEL_COMPILER" -eq 0 ]]; then
|
||||
AC_MSG_RESULT([no])
|
||||
else
|
||||
GCC_IS_INTEL=yes
|
||||
AM_CONDITIONAL(INTEL, true)
|
||||
gcc_version=`icc -dumpversion`
|
||||
AC_MSG_RESULT([yes ($gcc_version)])
|
||||
fi
|
||||
|
||||
#AC_SUBST(GCC_IS_INTEL)
|
||||
|
||||
ULIB_LIBS=
|
||||
MODULE_LIBTOOL_OPTIONS="-shared -export-dynamic -avoid-version"
|
||||
|
||||
|
@ -550,10 +572,9 @@ AM_CONDITIONAL(MS_LIB_AVAILABLE, test x$ms_librarian = xyes)
|
|||
|
||||
# Check for the compiler support
|
||||
gcc_major_4_1="no"
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes" -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
# We don't want gcc 2.7
|
||||
AC_MSG_CHECKING([for a supported version of gcc])
|
||||
gcc_version=`$CC -dumpversion`
|
||||
case "$gcc_version" in
|
||||
1.*|2.7.*|2.8.*)
|
||||
AC_MSG_RESULT([no ($gcc_version)])
|
||||
|
@ -716,7 +737,7 @@ if test "$enable_stdcpp" = "yes"; then
|
|||
else
|
||||
AC_MSG_RESULT(no)
|
||||
AM_CONDITIONAL(STDCPP, false)
|
||||
if test x"$GCC" = "xyes" ; then
|
||||
if test "x$GCC_IS_GNU" = xyes ; then
|
||||
lcflags="-nodefaultlibs -nostdinc++"
|
||||
else
|
||||
lcflags="-library=no%Cstd -features=no%except -features=no%rtti"
|
||||
|
@ -2529,7 +2550,7 @@ fi
|
|||
|
||||
# If gcc compiler add values to *FLAGS...
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes" -a "x$OPERATINGSYSTEM" = xlinux; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "x$OPERATINGSYSTEM" = xlinux; then
|
||||
|
||||
TWOCAN_CONF_MSG(Checking for $CC compiler flags)
|
||||
|
||||
|
@ -2778,9 +2799,9 @@ AM_CONDITIONAL(DOXY, test "$DOXYGEN" != "no")
|
|||
case "$target_os" in
|
||||
*bsd*)
|
||||
if test "$enable_stdcpp" != "yes"; then
|
||||
if test "$GCC" = "yes" -a "$ULIB_LIBC" = "-lc" ; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "$ULIB_LIBC" = "-lc" ; then
|
||||
ULIB_LIBC="-Wl,-lc"
|
||||
elif test "$GCC" = "yes" -a "$ULIB_LIBC" = "-lc_r" ; then
|
||||
elif test "x$GCC_IS_GNU" = xyes -a "$ULIB_LIBC" = "-lc_r" ; then
|
||||
ULIB_LIBC="-Wl,-lc_r"
|
||||
fi
|
||||
fi
|
||||
|
@ -2853,7 +2874,7 @@ if test "x$ac_cv_crc32_intrinsics" = xyes; then
|
|||
fi
|
||||
##########################
|
||||
|
||||
if test "$ac_cv_c_compiler_gnu" = "yes" -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
if test "x$GCC_IS_GNU" = xyes -a "x$GCC_IS_CLANG" = xno -a "x$GCC_IS_INTEL" = xno; then
|
||||
if test "$enable_static" = "yes" -a "$enable_shared" = "no" -a "$enable_stdcpp" = "yes"; then
|
||||
|
||||
## if test -f "$gcc_dir/libstdc++.a"; then
|
||||
|
@ -2992,7 +3013,7 @@ fi
|
|||
TWOCAN_CONF_MSG(Output Substitution)
|
||||
|
||||
# Create compiler version string
|
||||
if test x"$GCC" = x"yes" ; then
|
||||
if test "x$GCC_IS_GNU" = xyes ; then
|
||||
cc_string=`${CC} --version | sed q`
|
||||
case $cc_string in [[A-Za-z]]*) ;; *) cc_string="GCC $cc_string";; esac
|
||||
elif test x"$SUN_STUDIO_CC" = x"yes" ; then
|
||||
|
|
|
@ -103,7 +103,7 @@ loop:
|
|||
|
||||
*ip = lip;
|
||||
|
||||
(void) UIPAddress::getBinaryForm(ip->c_str(), addr, true);
|
||||
(void) UIPAddress::getBinaryForm(*ip, addr, true);
|
||||
|
||||
(void) rc->hmset(U_CONSTANT_TO_PARAM("CAPTIVE:id:%u ip %v"), addr, ip->rep);
|
||||
(void) rc->zadd(U_CONSTANT_TO_PARAM("CAPTIVE:byId 0 id:%u"), addr);
|
||||
|
@ -380,9 +380,9 @@ static void usp_end_wi_auth2()
|
|||
|
||||
static bool setLabelAndNetmaskFromAnagrafica(UString& label, UString& netmask)
|
||||
{
|
||||
U_TRACE(5, "::setLabelAndNetmaskFromAnagrafica(%p,%p,%p)", &label, &netmask)
|
||||
U_TRACE(5, "::setLabelAndNetmaskFromAnagrafica(%p,%p)", &label, &netmask)
|
||||
|
||||
U_INTERNAL_DUMP("ap_address = %V", ap_address)
|
||||
U_INTERNAL_DUMP("ap_address = %V", ap_address->rep)
|
||||
|
||||
U_INTERNAL_ASSERT(*ap_address)
|
||||
|
||||
|
@ -393,14 +393,18 @@ static bool setLabelAndNetmaskFromAnagrafica(UString& label, UString& netmask)
|
|||
*/
|
||||
|
||||
loop:
|
||||
pos = db_anagrafica->find(*ap_address, pos);
|
||||
U_INTERNAL_DUMP("pos = %u db_anagrafica->size() = %u", pos, db_anagrafica->size())
|
||||
|
||||
U_INTERNAL_DUMP("pos = %u", pos)
|
||||
if (pos >= db_anagrafica->size()) U_RETURN(false);
|
||||
|
||||
pos = db_anagrafica->find(*ap_address, pos);
|
||||
|
||||
if (pos == U_NOT_FOUND) U_RETURN(false);
|
||||
|
||||
pos += ap_address->size();
|
||||
|
||||
U_INTERNAL_DUMP("db_anagrafica->c_char(%u) = %C", pos, db_anagrafica->c_char(pos))
|
||||
|
||||
if (db_anagrafica->c_char(pos) != ',') goto loop;
|
||||
|
||||
if (pos != U_NOT_FOUND)
|
||||
|
@ -511,7 +515,7 @@ static bool setAccessPoint()
|
|||
*ap_address = ap->substr(pos1+1, pos2-pos1-1).copy();
|
||||
|
||||
if (*ap_address &&
|
||||
UIPAddress::getBinaryForm(ap_address->c_str(), addr, true) == false)
|
||||
UIPAddress::getBinaryForm(*ap_address, addr, true) == false)
|
||||
{
|
||||
U_LOGGER("*** AP ADDRESS(%v) NOT VALID ***", ap_address->rep);
|
||||
|
||||
|
@ -948,7 +952,7 @@ static void lostSession(int bclean)
|
|||
*ap_address = rc->getString(0);
|
||||
*ap_hostname = rc->getString(1);
|
||||
|
||||
(void) UIPAddress::getBinaryForm(ip->c_str(), ip_peer);
|
||||
(void) UIPAddress::getBinaryForm(*ip, ip_peer);
|
||||
|
||||
addToLogout(*ap_label);
|
||||
}
|
||||
|
@ -1100,7 +1104,7 @@ static void GET_checkCaptive()
|
|||
{
|
||||
*ap_address = vec[i];
|
||||
|
||||
(void) UIPAddress::getBinaryForm(ap_address->c_str(), addr, true);
|
||||
(void) UIPAddress::getBinaryForm(*ap_address, addr, true);
|
||||
|
||||
url.snprintf(U_CONSTANT_TO_PARAM("http://%v:5280/ping"), ap_address->rep);
|
||||
|
||||
|
@ -1318,7 +1322,7 @@ static void GET_logout()
|
|||
|
||||
if (getSession(*mac, *ap_label, U_CONSTANT_TO_PARAM("GET_logout")))
|
||||
{
|
||||
(void) UIPAddress::getBinaryForm(ip->c_str(), ip_peer);
|
||||
(void) UIPAddress::getBinaryForm(*ip, ip_peer);
|
||||
|
||||
idx = 0;
|
||||
|
||||
|
@ -1550,7 +1554,9 @@ static void POST_login()
|
|||
|
||||
// U_LOGGER("*** SESSION(%V) created at POST_login() ***", key_session->rep);
|
||||
|
||||
(void) rc->zadd(U_CONSTANT_TO_PARAM("SESSION:byCaptiveIdAndApId %u%06u deviceId:%v;ip:%v"), addr, ap_label->strtoul(), mac->rep, ip->rep);
|
||||
const char* ptr = getKeySessionPointer();
|
||||
|
||||
(void) rc->zadd(U_CONSTANT_TO_PARAM("SESSION:byCaptiveIdAndApId %u%06u %.*s"), addr, ap_label->strtoul(), key_session->remain(ptr), ptr);
|
||||
(void) rc->zadd(U_CONSTANT_TO_PARAM("SESSION:byLastUpdate %u %v"), u_now->tv_sec, key_session->rep);
|
||||
}
|
||||
|
||||
|
|
|
@ -3455,7 +3455,7 @@ next:
|
|||
|
||||
if (pvallow)
|
||||
{
|
||||
if (UIPAllow::isAllowed(user_rec->_ip.data(), *pvallow))
|
||||
if (UIPAllow::isAllowed(user_rec->_ip, *pvallow))
|
||||
{
|
||||
*uid = db_user->getKeyID();
|
||||
|
||||
|
|
|
@ -62,6 +62,9 @@
|
|||
/* Define to 1 if the fallocate() function is supported */
|
||||
#undef FALLOCATE_IS_SUPPORTED
|
||||
|
||||
/* Define if we are using gcc compiler */
|
||||
#undef GCC_IS_GNU
|
||||
|
||||
/* GNU C/C++ Compiler version */
|
||||
#undef GCC_VERSION
|
||||
|
||||
|
|
|
@ -1204,8 +1204,10 @@ private:
|
|||
class UCompileTimeRESPEncoder : public UCompileTimeStringFormatter {
|
||||
private:
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
|
||||
#endif
|
||||
|
||||
template<bool isPartial, size_t workingIndex = 0, size_t workingSegmentCount = 0, typename StringClass, typename... Xs, typename T, typename... Ts>
|
||||
static constexpr auto generateSegments(StringClass format, size_t& outputCount, std::tuple<Xs...>&& workingCommand, T&& t, Ts&&... ts)
|
||||
|
@ -1258,7 +1260,10 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
template<bool isPartial, bool overwrite, auto format, typename... Ts>
|
||||
static size_t encode_impl(size_t writePosition, UString& workingString, Ts&&... ts)
|
||||
|
|
|
@ -118,9 +118,8 @@ public:
|
|||
|
||||
// Check whether a ip address client ought to be allowed (belong to the same network)...
|
||||
|
||||
inline bool isAllowed(const char* ip_client);
|
||||
|
||||
bool isAllowed(UString& ip_client) { return isAllowed(ip_client.c_str()); }
|
||||
inline bool isAllowed(const UString& ip_client) { return isAllowed(U_STRING_TO_PARAM(ip_client)); }
|
||||
inline bool isAllowed(const char* ip_client, uint32_t len);
|
||||
|
||||
bool isAllowed(in_addr_t client) __pure;
|
||||
bool isAllowed(in_addr_t ifa_addr, in_addr_t ifa_netmask)
|
||||
|
@ -163,13 +162,13 @@ public:
|
|||
U_RETURN(U_NOT_FOUND);
|
||||
}
|
||||
|
||||
static uint32_t find(const char* ip_client, UVector<UIPAllow*>& vipallow)
|
||||
static uint32_t find(const char* ip_client, uint32_t len, UVector<UIPAllow*>& vipallow)
|
||||
{
|
||||
U_TRACE(0, "UIPAllow::find(%S,%p)", ip_client, &vipallow)
|
||||
U_TRACE(0, "UIPAllow::find(%.*S,%u,%p)", len, ip_client, len, &vipallow)
|
||||
|
||||
for (uint32_t i = 0, vlen = vipallow.size(); i < vlen; ++i)
|
||||
{
|
||||
if (vipallow[i]->isAllowed(ip_client)) U_RETURN(i);
|
||||
if (vipallow[i]->isAllowed(ip_client, len)) U_RETURN(i);
|
||||
}
|
||||
|
||||
U_RETURN(U_NOT_FOUND);
|
||||
|
@ -187,9 +186,9 @@ public:
|
|||
U_RETURN(U_NOT_FOUND);
|
||||
}
|
||||
|
||||
static bool isAllowed(in_addr_t client, UVector<UIPAllow*>& vipallow) { return (find( client, vipallow) != U_NOT_FOUND); }
|
||||
static bool isAllowed(const char* ip_client, UVector<UIPAllow*>& vipallow) { return (find(ip_client, vipallow) != U_NOT_FOUND); }
|
||||
static bool isAllowed(const UString& ip_client, UVector<UIPAllow*>& vipallow) { return (find(ip_client, vipallow) != U_NOT_FOUND); }
|
||||
static bool isAllowed(in_addr_t client, UVector<UIPAllow*>& vipallow) { return (find( client, vipallow) != U_NOT_FOUND); }
|
||||
static bool isAllowed(const char* ip_client, uint32_t len, UVector<UIPAllow*>& vipallow) { return (find(ip_client, len, vipallow) != U_NOT_FOUND); }
|
||||
static bool isAllowed(const UString& ip_client, UVector<UIPAllow*>& vipallow) { return (find(ip_client, vipallow) != U_NOT_FOUND); }
|
||||
|
||||
// DEBUG
|
||||
|
||||
|
@ -298,20 +297,8 @@ public:
|
|||
// converts the internet address from the IPv4 numbers-and-dots notation into binary form
|
||||
// (in network byte order) and stores it in the structure that points to
|
||||
|
||||
static bool getBinaryForm(const char* addr_str, uint32_t& addr, bool bconvert = false)
|
||||
{
|
||||
U_TRACE(0, "UIPAddress::getBinaryForm(%S,%p,%b)", addr_str, &addr, bconvert)
|
||||
|
||||
U_INTERNAL_ASSERT(u_isIPv4Addr(addr_str, u__strlen(addr_str, __PRETTY_FUNCTION__)))
|
||||
|
||||
struct in_addr ia;
|
||||
|
||||
if (U_SYSCALL(inet_aton, "%p,%p", addr_str, &ia) == 0) U_RETURN(false);
|
||||
|
||||
addr = (bconvert ? ntohl(ia.s_addr) : ia.s_addr);
|
||||
|
||||
U_RETURN(true);
|
||||
}
|
||||
static bool getBinaryForm(const UString& addr_str, uint32_t& addr, bool bconvert = false) { return getBinaryForm(U_STRING_TO_PARAM(addr_str), addr, bconvert); }
|
||||
static bool getBinaryForm(const char* addr_str, uint32_t len, uint32_t& addr, bool bconvert = false);
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/********************************************************************************/
|
||||
|
@ -466,13 +453,13 @@ private:
|
|||
friend class UClientImage_Base;
|
||||
};
|
||||
|
||||
inline bool UIPAllow::isAllowed(const char* ip_client)
|
||||
inline bool UIPAllow::isAllowed(const char* ip_client, uint32_t len)
|
||||
{
|
||||
U_TRACE(0, "UIPAllow::isAllowed(%S)", ip_client)
|
||||
U_TRACE(0, "UIPAllow::isAllowed(%.*S,%u)", len, ip_client, len)
|
||||
|
||||
in_addr_t client;
|
||||
|
||||
if (UIPAddress::getBinaryForm(ip_client, client) &&
|
||||
if (UIPAddress::getBinaryForm(ip_client, len, client) &&
|
||||
isAllowed(client))
|
||||
{
|
||||
U_RETURN(true);
|
||||
|
@ -480,5 +467,4 @@ inline bool UIPAllow::isAllowed(const char* ip_client)
|
|||
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -259,6 +259,8 @@ public:
|
|||
* template <typename...Ts> void use(Ts&&... ts) { (bindParam(UOrmTypeHandler<Ts>(ts)), ...); } NB: don't work!
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
template <class T1>
|
||||
void use(T1& r1);
|
||||
|
||||
|
@ -476,6 +478,8 @@ private:
|
|||
|
||||
// Syntactic sugar for bindParam() used with use() binding registers
|
||||
|
||||
/*
|
||||
*/
|
||||
template <class T1>
|
||||
inline void UOrmStatement::use(T1& r1)
|
||||
{
|
||||
|
|
|
@ -677,8 +677,10 @@ public:
|
|||
|
||||
// INIT
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
static void setStack(uint8_t* ptr, uint32_t len)
|
||||
{
|
||||
|
@ -688,7 +690,9 @@ public:
|
|||
stack_max = len / UFlatBufferValue::size();
|
||||
}
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
static void setBuffer(uint8_t* ptr, uint32_t len)
|
||||
{
|
||||
|
|
|
@ -2895,8 +2895,10 @@ public:
|
|||
else return substr<From>(std::make_index_sequence<To - From>{});
|
||||
}
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
|
||||
#endif
|
||||
|
||||
template<size_t index = 0>
|
||||
constexpr bool contains(char value) const
|
||||
|
@ -2906,7 +2908,9 @@ public:
|
|||
else return contains<index+1>(value);
|
||||
}
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
// so that CTV is transparently a UString to U_STRING_TO_PARAM
|
||||
char const *data() const noexcept { return string; }
|
||||
|
@ -2963,8 +2967,10 @@ static void snprintf_specialization(Lambda&& lambda, T t)
|
|||
class UCompileTimeStringFormatter {
|
||||
protected:
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-parameter"
|
||||
#endif
|
||||
|
||||
template<size_t workingIndex, size_t argumentCount, typename StringClass, typename T, typename... Ts>
|
||||
static constexpr auto generateSegments(StringClass format, T&& t, Ts&&... ts)
|
||||
|
@ -2982,7 +2988,9 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
template <typename T, typename U>
|
||||
struct decay_equiv : std::is_same<typename std::decay<T>::type, U>::type {};
|
||||
|
|
|
@ -656,6 +656,70 @@ UString UIPAddress::toString(uint8_t* addr)
|
|||
U_RETURN_STRING(x);
|
||||
}
|
||||
|
||||
bool UIPAddress::getBinaryForm(const char* addr_str, uint32_t len, uint32_t& addr, bool bconvert)
|
||||
{
|
||||
U_TRACE(0, "UIPAddress::getBinaryForm(%.*S,%u,%p,%b)", len, addr_str, len, &addr, bconvert)
|
||||
|
||||
uint32_t i;
|
||||
const char* ptr;
|
||||
unsigned long a[4] = { 0 };
|
||||
const char* p = addr_str;
|
||||
const char* end = addr_str + len;
|
||||
|
||||
for (i = 0; i < 4; ++i)
|
||||
{
|
||||
if (u__isdigit(*(ptr = p)) == false) U_RETURN(false);
|
||||
|
||||
while (u__isdigit(*p)) ++p;
|
||||
|
||||
a[i] = u_strtoul(ptr, p);
|
||||
|
||||
if (p >= end) break;
|
||||
|
||||
if (*p++ != '.') U_RETURN(false);
|
||||
}
|
||||
|
||||
U_INTERNAL_ASSERT(u_isIPv4Addr(addr_str, len))
|
||||
|
||||
switch (i)
|
||||
{
|
||||
case 0: a[1] = a[0] & 0xffffff; a[0] >>= 24; /* FALL THRU */
|
||||
case 1: a[2] = a[1] & 0x00ffff; a[1] >>= 16; /* FALL THRU */
|
||||
case 2: a[3] = a[2] & 0x0000ff; a[2] >>= 8; /* FALL THRU */
|
||||
case 3: break;
|
||||
case 4: U_RETURN(false);
|
||||
}
|
||||
|
||||
if (a[0] > 255 ||
|
||||
a[1] > 255 ||
|
||||
a[2] > 255 ||
|
||||
a[3] > 255)
|
||||
{
|
||||
U_RETURN(false);
|
||||
}
|
||||
|
||||
unsigned char* d = (unsigned char*)&addr;
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
if (bconvert)
|
||||
{
|
||||
d[0] = a[3];
|
||||
d[1] = a[2];
|
||||
d[2] = a[1];
|
||||
d[3] = a[0];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
d[0] = a[0];
|
||||
d[1] = a[1];
|
||||
d[2] = a[2];
|
||||
d[3] = a[3];
|
||||
}
|
||||
|
||||
U_RETURN(true);
|
||||
}
|
||||
|
||||
// Simple IP-based access-control system
|
||||
// Interpret a "HOST/BITS" IP mask specification. (Ex. 192.168.1.64/28)
|
||||
|
||||
|
@ -665,7 +729,7 @@ bool UIPAllow::parseMask(const UString& spec)
|
|||
|
||||
// get bit before slash
|
||||
|
||||
char addr_str[U_INET_ADDRSTRLEN];
|
||||
char addr_str[U_INET_ADDRSTRLEN+1];
|
||||
uint32_t len, addr_len = spec.find('/');
|
||||
|
||||
// extract and parse addr part
|
||||
|
|
|
@ -1282,7 +1282,7 @@ bool UNoCatPlugIn::creatNewPeer(uint32_t index_AUTH)
|
|||
|
||||
U_INTERNAL_ASSERT_EQUALS(peer, U_NULLPTR)
|
||||
|
||||
uint32_t index_network = UIPAllow::find(UServer_Base::client_address, *vLocalNetworkMask);
|
||||
uint32_t index_network = UIPAllow::find(U_CLIENT_ADDRESS_TO_PARAM, *vLocalNetworkMask);
|
||||
|
||||
U_INTERNAL_DUMP("index_network = %u", index_network)
|
||||
|
||||
|
@ -1930,7 +1930,7 @@ __pure uint32_t UNoCatPlugIn::getIndexAUTH(const char* ip_address)
|
|||
{
|
||||
// NB: we are multi portal, we must find which portal we indicate to redirect the client...
|
||||
|
||||
index_AUTH = UIPAllow::find(ip_address, *vLocalNetworkMask);
|
||||
index_AUTH = UIPAllow::find(ip_address, strlen(ip_address), *vLocalNetworkMask);
|
||||
|
||||
if (index_AUTH >= sz_AUTH) index_AUTH = 0;
|
||||
}
|
||||
|
|
|
@ -1449,7 +1449,7 @@ next: eraseTimer();
|
|||
|
||||
if (checkUrl(buffer, sizeof(buffer), sz, U_CONSTANT_TO_PARAM("NEW")) == 0) goto end;
|
||||
|
||||
index_network = UIPAllow::find(UServer_Base::client_address, *vLocalNetworkMask);
|
||||
index_network = UIPAllow::find(U_CLIENT_ADDRESS_TO_PARAM, *vLocalNetworkMask);
|
||||
|
||||
U_INTERNAL_DUMP("index_network = %u", index_network)
|
||||
|
||||
|
|
|
@ -3200,7 +3200,7 @@ next:
|
|||
{
|
||||
in_addr_t addr;
|
||||
|
||||
if (UIPAddress::getBinaryForm(IP_address->c_str(), addr) == false) U_ERROR("IP_ADDRESS conversion fail: %V", IP_address->rep);
|
||||
if (UIPAddress::getBinaryForm(*IP_address, addr) == false) U_ERROR("IP_ADDRESS conversion fail: %V", IP_address->rep);
|
||||
|
||||
socket->setAddress(&addr);
|
||||
|
||||
|
|
|
@ -257,8 +257,10 @@ retry:
|
|||
(void) U_SYSCALL(sigaction, "%d,%p,%p", SIGSEGV, old + SIGSEGV, U_NULLPTR);
|
||||
}
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsuggest-attribute=noreturn"
|
||||
#endif
|
||||
|
||||
RETSIGTYPE UInterrupt::handlerSegvWithInfo(int signo, siginfo_t* info, void* context)
|
||||
{
|
||||
|
@ -295,7 +297,9 @@ RETSIGTYPE UInterrupt::handlerSegvWithInfo(int signo, siginfo_t* info, void* con
|
|||
::abort();
|
||||
}
|
||||
|
||||
#ifdef GCC_IS_GNU
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
void UInterrupt::getSignalInfo(int signo, siginfo_t* info)
|
||||
{
|
||||
|
|
|
@ -8559,7 +8559,7 @@ bool UHTTP::checkUriProtected()
|
|||
if (ok &&
|
||||
U_http_ip_client_len)
|
||||
{
|
||||
ok = UIPAllow::isAllowed(UServer_Base::client_address, *vallow_IP);
|
||||
ok = UIPAllow::isAllowed(U_CLIENT_ADDRESS_TO_PARAM, *vallow_IP);
|
||||
}
|
||||
|
||||
if (ok == false)
|
||||
|
|
|
@ -654,7 +654,7 @@ bool UWebSocket::sendData(const bool isServer, USocket* socket, int type, const
|
|||
# ifdef USE_LIBBROTLI
|
||||
UString compressed;
|
||||
|
||||
if (compressed = UStringExt::brotli(data, len, (U_PARALLELIZATION_CHILD ? BROTLI_MAX_QUALITY : UHTTP::brotli_level_for_dynamic_content)))
|
||||
if ((compressed = UStringExt::brotli(data, len, (U_PARALLELIZATION_CHILD ? BROTLI_MAX_QUALITY : UHTTP::brotli_level_for_dynamic_content))))
|
||||
{
|
||||
opcode = U_WS_OPCODE_BROTLI;
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
06F6
|
||||
073C
|
||||
|
|
|
@ -18,7 +18,7 @@ PRG = test_timeval test_timer test_notifier test_string \
|
|||
test_services test_base64 test_header test_entity \
|
||||
test_ipaddress test_socket test_ftp test_http test_rdb_client \
|
||||
test_tokenizer test_query_parser test_multipart test_command test_dialog test_json test_redis test_elasticsearch \
|
||||
test_smtp test_pop3 test_imap test_hash_map test_serialize
|
||||
test_smtp test_pop3 test_imap test_hash_map test_serialize eval_itoa eval_dtoa
|
||||
## test_twilio
|
||||
|
||||
TST = timeval.test timer.test notifier.test string.test \
|
||||
|
@ -103,6 +103,8 @@ test_mongodb_SOURCES = test_mongodb.cpp
|
|||
test_elasticsearch_SOURCES = test_elasticsearch.cpp
|
||||
test_hash_map_SOURCES = test_hash_map.cpp
|
||||
test_serialize_SOURCES = test_serialize.cpp
|
||||
eval_itoa_SOURCES = eval_itoa.cpp tsc.h branchlut.h
|
||||
eval_dtoa_SOURCES = eval_dtoa.cpp tsc.h dtoa_milo.h
|
||||
|
||||
if PTHREAD
|
||||
PRG += test_thread
|
||||
|
|
|
@ -218,13 +218,22 @@ am__EXEEXT_19 = test_timeval$(EXEEXT) test_timer$(EXEEXT) \
|
|||
test_dialog$(EXEEXT) test_json$(EXEEXT) test_redis$(EXEEXT) \
|
||||
test_elasticsearch$(EXEEXT) test_smtp$(EXEEXT) \
|
||||
test_pop3$(EXEEXT) test_imap$(EXEEXT) test_hash_map$(EXEEXT) \
|
||||
test_serialize$(EXEEXT) $(am__EXEEXT_1) $(am__EXEEXT_2) \
|
||||
$(am__EXEEXT_3) $(am__EXEEXT_4) $(am__EXEEXT_5) \
|
||||
$(am__EXEEXT_6) $(am__EXEEXT_7) $(am__EXEEXT_8) \
|
||||
$(am__EXEEXT_9) $(am__EXEEXT_10) $(am__EXEEXT_2) \
|
||||
$(am__EXEEXT_3) $(am__EXEEXT_11) $(am__EXEEXT_12) \
|
||||
$(am__EXEEXT_13) $(am__EXEEXT_14) $(am__EXEEXT_15) \
|
||||
$(am__EXEEXT_16) $(am__EXEEXT_17) $(am__EXEEXT_18)
|
||||
test_serialize$(EXEEXT) eval_itoa$(EXEEXT) eval_dtoa$(EXEEXT) \
|
||||
$(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
$(am__EXEEXT_4) $(am__EXEEXT_5) $(am__EXEEXT_6) \
|
||||
$(am__EXEEXT_7) $(am__EXEEXT_8) $(am__EXEEXT_9) \
|
||||
$(am__EXEEXT_10) $(am__EXEEXT_2) $(am__EXEEXT_3) \
|
||||
$(am__EXEEXT_11) $(am__EXEEXT_12) $(am__EXEEXT_13) \
|
||||
$(am__EXEEXT_14) $(am__EXEEXT_15) $(am__EXEEXT_16) \
|
||||
$(am__EXEEXT_17) $(am__EXEEXT_18)
|
||||
am_eval_dtoa_OBJECTS = eval_dtoa.$(OBJEXT)
|
||||
eval_dtoa_OBJECTS = $(am_eval_dtoa_OBJECTS)
|
||||
eval_dtoa_LDADD = $(LDADD)
|
||||
eval_dtoa_DEPENDENCIES = $(top_builddir)/src/ulib/lib@ULIB@.la
|
||||
am_eval_itoa_OBJECTS = eval_itoa.$(OBJEXT)
|
||||
eval_itoa_OBJECTS = $(am_eval_itoa_OBJECTS)
|
||||
eval_itoa_LDADD = $(LDADD)
|
||||
eval_itoa_DEPENDENCIES = $(top_builddir)/src/ulib/lib@ULIB@.la
|
||||
am_test_application_OBJECTS = test_application.$(OBJEXT)
|
||||
test_application_OBJECTS = $(am_test_application_OBJECTS)
|
||||
test_application_LDADD = $(LDADD)
|
||||
|
@ -595,7 +604,26 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
|
|||
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
|
||||
am__v_CXXLD_0 = @echo " CXXLD " $@;
|
||||
am__v_CXXLD_1 =
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
|
||||
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
|
||||
$(AM_CFLAGS) $(CFLAGS)
|
||||
AM_V_CC = $(am__v_CC_@AM_V@)
|
||||
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
|
||||
am__v_CC_0 = @echo " CC " $@;
|
||||
am__v_CC_1 =
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
|
||||
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
|
||||
$(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
|
||||
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
|
||||
am__v_CCLD_0 = @echo " CCLD " $@;
|
||||
am__v_CCLD_1 =
|
||||
SOURCES = $(product1_la_SOURCES) $(product2_la_SOURCES) \
|
||||
$(eval_dtoa_SOURCES) $(eval_itoa_SOURCES) \
|
||||
$(test_application_SOURCES) $(test_arping_SOURCES) \
|
||||
$(test_base64_SOURCES) $(test_bit_array_SOURCES) \
|
||||
$(test_cache_SOURCES) $(test_cdb_SOURCES) \
|
||||
|
@ -633,7 +661,8 @@ SOURCES = $(product1_la_SOURCES) $(product2_la_SOURCES) \
|
|||
$(test_unixsocket_server_SOURCES) $(test_url_SOURCES) \
|
||||
$(test_vector_SOURCES) $(test_zip_SOURCES)
|
||||
DIST_SOURCES = $(am__product1_la_SOURCES_DIST) \
|
||||
$(am__product2_la_SOURCES_DIST) $(test_application_SOURCES) \
|
||||
$(am__product2_la_SOURCES_DIST) $(eval_dtoa_SOURCES) \
|
||||
$(eval_itoa_SOURCES) $(test_application_SOURCES) \
|
||||
$(am__test_arping_SOURCES_DIST) $(test_base64_SOURCES) \
|
||||
$(test_bit_array_SOURCES) $(test_cache_SOURCES) \
|
||||
$(test_cdb_SOURCES) $(am__test_certificate_SOURCES_DIST) \
|
||||
|
@ -1118,13 +1147,14 @@ PRG = test_timeval test_timer test_notifier test_string test_file \
|
|||
test_http test_rdb_client test_tokenizer test_query_parser \
|
||||
test_multipart test_command test_dialog test_json test_redis \
|
||||
test_elasticsearch test_smtp test_pop3 test_imap test_hash_map \
|
||||
test_serialize $(am__append_1) $(am__append_3) $(am__append_4) \
|
||||
$(am__append_5) $(am__append_6) $(am__append_8) \
|
||||
$(am__append_10) $(am__append_12) $(am__append_14) \
|
||||
$(am__append_16) $(am__append_18) $(am__append_20) \
|
||||
$(am__append_22) $(am__append_24) $(am__append_26) \
|
||||
$(am__append_28) $(am__append_30) $(am__append_32) \
|
||||
$(am__append_34) $(am__append_36)
|
||||
test_serialize eval_itoa eval_dtoa $(am__append_1) \
|
||||
$(am__append_3) $(am__append_4) $(am__append_5) \
|
||||
$(am__append_6) $(am__append_8) $(am__append_10) \
|
||||
$(am__append_12) $(am__append_14) $(am__append_16) \
|
||||
$(am__append_18) $(am__append_20) $(am__append_22) \
|
||||
$(am__append_24) $(am__append_26) $(am__append_28) \
|
||||
$(am__append_30) $(am__append_32) $(am__append_34) \
|
||||
$(am__append_36)
|
||||
TST = timeval.test timer.test notifier.test string.test file.test \
|
||||
cdb.test rdb.test file_config.test log.test vector.test \
|
||||
options.test application.test tree.test compress.test \
|
||||
|
@ -1188,6 +1218,8 @@ test_mongodb_SOURCES = test_mongodb.cpp
|
|||
test_elasticsearch_SOURCES = test_elasticsearch.cpp
|
||||
test_hash_map_SOURCES = test_hash_map.cpp
|
||||
test_serialize_SOURCES = test_serialize.cpp
|
||||
eval_itoa_SOURCES = eval_itoa.cpp tsc.h branchlut.h
|
||||
eval_dtoa_SOURCES = eval_dtoa.cpp tsc.h dtoa_milo.h
|
||||
@PTHREAD_TRUE@test_thread_SOURCES = test_thread.cpp
|
||||
@ZIP_TRUE@test_zip_SOURCES = test_zip.cpp
|
||||
@LIBTDB_TRUE@test_tdb_SOURCES = test_tdb.cpp
|
||||
|
@ -1293,6 +1325,14 @@ clean-checkPROGRAMS:
|
|||
echo " rm -f" $$list; \
|
||||
rm -f $$list
|
||||
|
||||
eval_dtoa$(EXEEXT): $(eval_dtoa_OBJECTS) $(eval_dtoa_DEPENDENCIES) $(EXTRA_eval_dtoa_DEPENDENCIES)
|
||||
@rm -f eval_dtoa$(EXEEXT)
|
||||
$(AM_V_CXXLD)$(CXXLINK) $(eval_dtoa_OBJECTS) $(eval_dtoa_LDADD) $(LIBS)
|
||||
|
||||
eval_itoa$(EXEEXT): $(eval_itoa_OBJECTS) $(eval_itoa_DEPENDENCIES) $(EXTRA_eval_itoa_DEPENDENCIES)
|
||||
@rm -f eval_itoa$(EXEEXT)
|
||||
$(AM_V_CXXLD)$(CXXLINK) $(eval_itoa_OBJECTS) $(eval_itoa_LDADD) $(LIBS)
|
||||
|
||||
test_application$(EXEEXT): $(test_application_OBJECTS) $(test_application_DEPENDENCIES) $(EXTRA_test_application_DEPENDENCIES)
|
||||
@rm -f test_application$(EXEEXT)
|
||||
$(AM_V_CXXLD)$(CXXLINK) $(test_application_OBJECTS) $(test_application_LDADD) $(LIBS)
|
||||
|
@ -1597,6 +1637,8 @@ mostlyclean-compile:
|
|||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_dtoa.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eval_itoa.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_application.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_arping.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_base64.Po@am__quote@
|
||||
|
|
|
@ -4,11 +4,11 @@ Four Debian releases are available on the main site:
|
|||
Debian 8.11, or jessie. Access this release through dists/oldoldstable
|
||||
Debian 8.11 was released Saturday, 23rd June 2018.
|
||||
|
||||
Debian 9.11, or stretch. Access this release through dists/oldstable
|
||||
Debian 9.11 was released Sunday, 8th September 2019.
|
||||
Debian 9.12, or stretch. Access this release through dists/oldstable
|
||||
Debian 9.12 was released Saturday, 8th February 2020.
|
||||
|
||||
Debian 10.1, or buster. Access this release through dists/stable
|
||||
Debian 10.1 was released Saturday, 7th September 2019.
|
||||
Debian 10.3, or buster. Access this release through dists/stable
|
||||
Debian 10.3 was released Saturday, 8th February 2020.
|
||||
|
||||
Testing, or bullseye. Access this release through dists/testing. The
|
||||
current tested development snapshot is named bullseye. Packages which
|
||||
|
|
409
tests/ulib/dtoa_milo.h
Normal file
409
tests/ulib/dtoa_milo.h
Normal file
|
@ -0,0 +1,409 @@
|
|||
// https://github.com/miloyip/dtoa-benchmark
|
||||
// Function Time (ns) Speedup
|
||||
// sprintf 1,256.376 1.00x
|
||||
// ...
|
||||
// milo 138.021 9.10x
|
||||
|
||||
#pragma once
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include "msinttypes/stdint.h"
|
||||
#include <intrin.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#define UINT64_C2(h, l) ((static_cast<uint64_t>(h) << 32) | static_cast<uint64_t>(l))
|
||||
|
||||
struct DiyFp {
|
||||
DiyFp() {}
|
||||
|
||||
DiyFp(uint64_t _f, int _e) : f(_f), e(_e) {}
|
||||
|
||||
DiyFp(double d) {
|
||||
union {
|
||||
double d;
|
||||
uint64_t u64;
|
||||
} u = { d };
|
||||
|
||||
int biased_e = (u.u64 & kDpExponentMask) >> kDpSignificandSize;
|
||||
uint64_t significand = (u.u64 & kDpSignificandMask);
|
||||
if (biased_e != 0) {
|
||||
f = significand + kDpHiddenBit;
|
||||
e = biased_e - kDpExponentBias;
|
||||
}
|
||||
else {
|
||||
f = significand;
|
||||
e = kDpMinExponent + 1;
|
||||
}
|
||||
}
|
||||
|
||||
DiyFp operator-(const DiyFp& rhs) const {
|
||||
assert(e == rhs.e);
|
||||
assert(f >= rhs.f);
|
||||
return DiyFp(f - rhs.f, e);
|
||||
}
|
||||
|
||||
DiyFp operator*(const DiyFp& rhs) const {
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
uint64_t h;
|
||||
uint64_t l = _umul128(f, rhs.f, &h);
|
||||
if (l & (uint64_t(1) << 63)) // rounding
|
||||
h++;
|
||||
return DiyFp(h, e + rhs.e + 64);
|
||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__x86_64__)
|
||||
unsigned __int128 p = static_cast<unsigned __int128>(f) * static_cast<unsigned __int128>(rhs.f);
|
||||
uint64_t h = p >> 64;
|
||||
uint64_t l = static_cast<uint64_t>(p);
|
||||
if (l & (uint64_t(1) << 63)) // rounding
|
||||
h++;
|
||||
return DiyFp(h, e + rhs.e + 64);
|
||||
#else
|
||||
const uint64_t M32 = 0xFFFFFFFF;
|
||||
const uint64_t a = f >> 32;
|
||||
const uint64_t b = f & M32;
|
||||
const uint64_t c = rhs.f >> 32;
|
||||
const uint64_t d = rhs.f & M32;
|
||||
const uint64_t ac = a * c;
|
||||
const uint64_t bc = b * c;
|
||||
const uint64_t ad = a * d;
|
||||
const uint64_t bd = b * d;
|
||||
uint64_t tmp = (bd >> 32) + (ad & M32) + (bc & M32);
|
||||
tmp += 1U << 31; /// mult_round
|
||||
return DiyFp(ac + (ad >> 32) + (bc >> 32) + (tmp >> 32), e + rhs.e + 64);
|
||||
#endif
|
||||
}
|
||||
|
||||
DiyFp Normalize() const {
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
unsigned long index;
|
||||
_BitScanReverse64(&index, f);
|
||||
return DiyFp(f << (63 - index), e - (63 - index));
|
||||
#elif defined(__GNUC__)
|
||||
int s = __builtin_clzll(f);
|
||||
return DiyFp(f << s, e - s);
|
||||
#else
|
||||
DiyFp res = *this;
|
||||
while (!(res.f & kDpHiddenBit)) {
|
||||
res.f <<= 1;
|
||||
res.e--;
|
||||
}
|
||||
res.f <<= (kDiySignificandSize - kDpSignificandSize - 1);
|
||||
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 1);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
DiyFp NormalizeBoundary() const {
|
||||
#if defined(_MSC_VER) && defined(_M_AMD64)
|
||||
unsigned long index;
|
||||
_BitScanReverse64(&index, f);
|
||||
return DiyFp (f << (63 - index), e - (63 - index));
|
||||
#else
|
||||
DiyFp res = *this;
|
||||
while (!(res.f & (kDpHiddenBit << 1))) {
|
||||
res.f <<= 1;
|
||||
res.e--;
|
||||
}
|
||||
res.f <<= (kDiySignificandSize - kDpSignificandSize - 2);
|
||||
res.e = res.e - (kDiySignificandSize - kDpSignificandSize - 2);
|
||||
return res;
|
||||
#endif
|
||||
}
|
||||
|
||||
void NormalizedBoundaries(DiyFp* minus, DiyFp* plus) const {
|
||||
DiyFp pl = DiyFp((f << 1) + 1, e - 1).NormalizeBoundary();
|
||||
DiyFp mi = (f == kDpHiddenBit) ? DiyFp((f << 2) - 1, e - 2) : DiyFp((f << 1) - 1, e - 1);
|
||||
mi.f <<= mi.e - pl.e;
|
||||
mi.e = pl.e;
|
||||
*plus = pl;
|
||||
*minus = mi;
|
||||
}
|
||||
|
||||
static const int kDiySignificandSize = 64;
|
||||
static const int kDpSignificandSize = 52;
|
||||
static const int kDpExponentBias = 0x3FF + kDpSignificandSize;
|
||||
static const int kDpMinExponent = -kDpExponentBias;
|
||||
static const uint64_t kDpExponentMask = UINT64_C2(0x7FF00000, 0x00000000);
|
||||
static const uint64_t kDpSignificandMask = UINT64_C2(0x000FFFFF, 0xFFFFFFFF);
|
||||
static const uint64_t kDpHiddenBit = UINT64_C2(0x00100000, 0x00000000);
|
||||
|
||||
uint64_t f;
|
||||
int e;
|
||||
};
|
||||
|
||||
inline DiyFp GetCachedPower(int e, int* K) {
|
||||
// 10^-348, 10^-340, ..., 10^340
|
||||
static const uint64_t kCachedPowers_F[] = {
|
||||
UINT64_C2(0xfa8fd5a0, 0x081c0288), UINT64_C2(0xbaaee17f, 0xa23ebf76),
|
||||
UINT64_C2(0x8b16fb20, 0x3055ac76), UINT64_C2(0xcf42894a, 0x5dce35ea),
|
||||
UINT64_C2(0x9a6bb0aa, 0x55653b2d), UINT64_C2(0xe61acf03, 0x3d1a45df),
|
||||
UINT64_C2(0xab70fe17, 0xc79ac6ca), UINT64_C2(0xff77b1fc, 0xbebcdc4f),
|
||||
UINT64_C2(0xbe5691ef, 0x416bd60c), UINT64_C2(0x8dd01fad, 0x907ffc3c),
|
||||
UINT64_C2(0xd3515c28, 0x31559a83), UINT64_C2(0x9d71ac8f, 0xada6c9b5),
|
||||
UINT64_C2(0xea9c2277, 0x23ee8bcb), UINT64_C2(0xaecc4991, 0x4078536d),
|
||||
UINT64_C2(0x823c1279, 0x5db6ce57), UINT64_C2(0xc2109436, 0x4dfb5637),
|
||||
UINT64_C2(0x9096ea6f, 0x3848984f), UINT64_C2(0xd77485cb, 0x25823ac7),
|
||||
UINT64_C2(0xa086cfcd, 0x97bf97f4), UINT64_C2(0xef340a98, 0x172aace5),
|
||||
UINT64_C2(0xb23867fb, 0x2a35b28e), UINT64_C2(0x84c8d4df, 0xd2c63f3b),
|
||||
UINT64_C2(0xc5dd4427, 0x1ad3cdba), UINT64_C2(0x936b9fce, 0xbb25c996),
|
||||
UINT64_C2(0xdbac6c24, 0x7d62a584), UINT64_C2(0xa3ab6658, 0x0d5fdaf6),
|
||||
UINT64_C2(0xf3e2f893, 0xdec3f126), UINT64_C2(0xb5b5ada8, 0xaaff80b8),
|
||||
UINT64_C2(0x87625f05, 0x6c7c4a8b), UINT64_C2(0xc9bcff60, 0x34c13053),
|
||||
UINT64_C2(0x964e858c, 0x91ba2655), UINT64_C2(0xdff97724, 0x70297ebd),
|
||||
UINT64_C2(0xa6dfbd9f, 0xb8e5b88f), UINT64_C2(0xf8a95fcf, 0x88747d94),
|
||||
UINT64_C2(0xb9447093, 0x8fa89bcf), UINT64_C2(0x8a08f0f8, 0xbf0f156b),
|
||||
UINT64_C2(0xcdb02555, 0x653131b6), UINT64_C2(0x993fe2c6, 0xd07b7fac),
|
||||
UINT64_C2(0xe45c10c4, 0x2a2b3b06), UINT64_C2(0xaa242499, 0x697392d3),
|
||||
UINT64_C2(0xfd87b5f2, 0x8300ca0e), UINT64_C2(0xbce50864, 0x92111aeb),
|
||||
UINT64_C2(0x8cbccc09, 0x6f5088cc), UINT64_C2(0xd1b71758, 0xe219652c),
|
||||
UINT64_C2(0x9c400000, 0x00000000), UINT64_C2(0xe8d4a510, 0x00000000),
|
||||
UINT64_C2(0xad78ebc5, 0xac620000), UINT64_C2(0x813f3978, 0xf8940984),
|
||||
UINT64_C2(0xc097ce7b, 0xc90715b3), UINT64_C2(0x8f7e32ce, 0x7bea5c70),
|
||||
UINT64_C2(0xd5d238a4, 0xabe98068), UINT64_C2(0x9f4f2726, 0x179a2245),
|
||||
UINT64_C2(0xed63a231, 0xd4c4fb27), UINT64_C2(0xb0de6538, 0x8cc8ada8),
|
||||
UINT64_C2(0x83c7088e, 0x1aab65db), UINT64_C2(0xc45d1df9, 0x42711d9a),
|
||||
UINT64_C2(0x924d692c, 0xa61be758), UINT64_C2(0xda01ee64, 0x1a708dea),
|
||||
UINT64_C2(0xa26da399, 0x9aef774a), UINT64_C2(0xf209787b, 0xb47d6b85),
|
||||
UINT64_C2(0xb454e4a1, 0x79dd1877), UINT64_C2(0x865b8692, 0x5b9bc5c2),
|
||||
UINT64_C2(0xc83553c5, 0xc8965d3d), UINT64_C2(0x952ab45c, 0xfa97a0b3),
|
||||
UINT64_C2(0xde469fbd, 0x99a05fe3), UINT64_C2(0xa59bc234, 0xdb398c25),
|
||||
UINT64_C2(0xf6c69a72, 0xa3989f5c), UINT64_C2(0xb7dcbf53, 0x54e9bece),
|
||||
UINT64_C2(0x88fcf317, 0xf22241e2), UINT64_C2(0xcc20ce9b, 0xd35c78a5),
|
||||
UINT64_C2(0x98165af3, 0x7b2153df), UINT64_C2(0xe2a0b5dc, 0x971f303a),
|
||||
UINT64_C2(0xa8d9d153, 0x5ce3b396), UINT64_C2(0xfb9b7cd9, 0xa4a7443c),
|
||||
UINT64_C2(0xbb764c4c, 0xa7a44410), UINT64_C2(0x8bab8eef, 0xb6409c1a),
|
||||
UINT64_C2(0xd01fef10, 0xa657842c), UINT64_C2(0x9b10a4e5, 0xe9913129),
|
||||
UINT64_C2(0xe7109bfb, 0xa19c0c9d), UINT64_C2(0xac2820d9, 0x623bf429),
|
||||
UINT64_C2(0x80444b5e, 0x7aa7cf85), UINT64_C2(0xbf21e440, 0x03acdd2d),
|
||||
UINT64_C2(0x8e679c2f, 0x5e44ff8f), UINT64_C2(0xd433179d, 0x9c8cb841),
|
||||
UINT64_C2(0x9e19db92, 0xb4e31ba9), UINT64_C2(0xeb96bf6e, 0xbadf77d9),
|
||||
UINT64_C2(0xaf87023b, 0x9bf0ee6b)
|
||||
};
|
||||
static const int16_t kCachedPowers_E[] = {
|
||||
-1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,
|
||||
-954, -927, -901, -874, -847, -821, -794, -768, -741, -715,
|
||||
-688, -661, -635, -608, -582, -555, -529, -502, -475, -449,
|
||||
-422, -396, -369, -343, -316, -289, -263, -236, -210, -183,
|
||||
-157, -130, -103, -77, -50, -24, 3, 30, 56, 83,
|
||||
109, 136, 162, 189, 216, 242, 269, 295, 322, 348,
|
||||
375, 402, 428, 455, 481, 508, 534, 561, 588, 614,
|
||||
641, 667, 694, 720, 747, 774, 800, 827, 853, 880,
|
||||
907, 933, 960, 986, 1013, 1039, 1066
|
||||
};
|
||||
|
||||
//int k = static_cast<int>(ceil((-61 - e) * 0.30102999566398114)) + 374;
|
||||
double dk = (-61 - e) * 0.30102999566398114 + 347; // dk must be positive, so can do ceiling in positive
|
||||
int k = static_cast<int>(dk);
|
||||
if (k != dk)
|
||||
k++;
|
||||
|
||||
unsigned index = static_cast<unsigned>((k >> 3) + 1);
|
||||
*K = -(-348 + static_cast<int>(index << 3)); // decimal exponent no need lookup table
|
||||
|
||||
assert(index < sizeof(kCachedPowers_F) / sizeof(kCachedPowers_F[0]));
|
||||
return DiyFp(kCachedPowers_F[index], kCachedPowers_E[index]);
|
||||
}
|
||||
|
||||
inline void GrisuRound(char* buffer, int len, uint64_t delta, uint64_t rest, uint64_t ten_kappa, uint64_t wp_w) {
|
||||
while (rest < wp_w && delta - rest >= ten_kappa &&
|
||||
(rest + ten_kappa < wp_w || /// closer
|
||||
wp_w - rest > rest + ten_kappa - wp_w)) {
|
||||
buffer[len - 1]--;
|
||||
rest += ten_kappa;
|
||||
}
|
||||
}
|
||||
|
||||
inline unsigned CountDecimalDigit32(uint32_t n) {
|
||||
// Simple pure C++ implementation was faster than __builtin_clz version in this situation.
|
||||
if (n < 10) return 1;
|
||||
if (n < 100) return 2;
|
||||
if (n < 1000) return 3;
|
||||
if (n < 10000) return 4;
|
||||
if (n < 100000) return 5;
|
||||
if (n < 1000000) return 6;
|
||||
if (n < 10000000) return 7;
|
||||
if (n < 100000000) return 8;
|
||||
if (n < 1000000000) return 9;
|
||||
return 10;
|
||||
}
|
||||
|
||||
inline void DigitGen(const DiyFp& W, const DiyFp& Mp, uint64_t delta, char* buffer, int* len, int* K) {
|
||||
static const uint32_t kPow10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000 };
|
||||
const DiyFp one(uint64_t(1) << -Mp.e, Mp.e);
|
||||
const DiyFp wp_w = Mp - W;
|
||||
uint32_t p1 = static_cast<uint32_t>(Mp.f >> -one.e);
|
||||
uint64_t p2 = Mp.f & (one.f - 1);
|
||||
int kappa = static_cast<int>(CountDecimalDigit32(p1));
|
||||
*len = 0;
|
||||
|
||||
while (kappa > 0) {
|
||||
uint32_t d;
|
||||
switch (kappa) {
|
||||
case 10: d = p1 / 1000000000; p1 %= 1000000000; break;
|
||||
case 9: d = p1 / 100000000; p1 %= 100000000; break;
|
||||
case 8: d = p1 / 10000000; p1 %= 10000000; break;
|
||||
case 7: d = p1 / 1000000; p1 %= 1000000; break;
|
||||
case 6: d = p1 / 100000; p1 %= 100000; break;
|
||||
case 5: d = p1 / 10000; p1 %= 10000; break;
|
||||
case 4: d = p1 / 1000; p1 %= 1000; break;
|
||||
case 3: d = p1 / 100; p1 %= 100; break;
|
||||
case 2: d = p1 / 10; p1 %= 10; break;
|
||||
case 1: d = p1; p1 = 0; break;
|
||||
default:
|
||||
#if defined(_MSC_VER)
|
||||
__assume(0);
|
||||
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
__builtin_unreachable();
|
||||
#else
|
||||
d = 0;
|
||||
#endif
|
||||
}
|
||||
if (d || *len)
|
||||
buffer[(*len)++] = '0' + static_cast<char>(d);
|
||||
kappa--;
|
||||
uint64_t tmp = (static_cast<uint64_t>(p1) << -one.e) + p2;
|
||||
if (tmp <= delta) {
|
||||
*K += kappa;
|
||||
GrisuRound(buffer, *len, delta, tmp, static_cast<uint64_t>(kPow10[kappa]) << -one.e, wp_w.f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// kappa = 0
|
||||
for (;;) {
|
||||
p2 *= 10;
|
||||
delta *= 10;
|
||||
char d = static_cast<char>(p2 >> -one.e);
|
||||
if (d || *len)
|
||||
buffer[(*len)++] = '0' + d;
|
||||
p2 &= one.f - 1;
|
||||
kappa--;
|
||||
if (p2 < delta) {
|
||||
*K += kappa;
|
||||
GrisuRound(buffer, *len, delta, p2, one.f, wp_w.f * kPow10[-kappa]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void Grisu2(double value, char* buffer, int* length, int* K) {
|
||||
const DiyFp v(value);
|
||||
DiyFp w_m, w_p;
|
||||
v.NormalizedBoundaries(&w_m, &w_p);
|
||||
|
||||
const DiyFp c_mk = GetCachedPower(w_p.e, K);
|
||||
const DiyFp W = v.Normalize() * c_mk;
|
||||
DiyFp Wp = w_p * c_mk;
|
||||
DiyFp Wm = w_m * c_mk;
|
||||
Wm.f++;
|
||||
Wp.f--;
|
||||
DigitGen(W, Wp, Wp.f - Wm.f, buffer, length, K);
|
||||
}
|
||||
|
||||
inline const char* GetDigitsLut() {
|
||||
static const char cDigitsLut[200] = {
|
||||
'0', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '0', '6', '0', '7', '0', '8', '0', '9',
|
||||
'1', '0', '1', '1', '1', '2', '1', '3', '1', '4', '1', '5', '1', '6', '1', '7', '1', '8', '1', '9',
|
||||
'2', '0', '2', '1', '2', '2', '2', '3', '2', '4', '2', '5', '2', '6', '2', '7', '2', '8', '2', '9',
|
||||
'3', '0', '3', '1', '3', '2', '3', '3', '3', '4', '3', '5', '3', '6', '3', '7', '3', '8', '3', '9',
|
||||
'4', '0', '4', '1', '4', '2', '4', '3', '4', '4', '4', '5', '4', '6', '4', '7', '4', '8', '4', '9',
|
||||
'5', '0', '5', '1', '5', '2', '5', '3', '5', '4', '5', '5', '5', '6', '5', '7', '5', '8', '5', '9',
|
||||
'6', '0', '6', '1', '6', '2', '6', '3', '6', '4', '6', '5', '6', '6', '6', '7', '6', '8', '6', '9',
|
||||
'7', '0', '7', '1', '7', '2', '7', '3', '7', '4', '7', '5', '7', '6', '7', '7', '7', '8', '7', '9',
|
||||
'8', '0', '8', '1', '8', '2', '8', '3', '8', '4', '8', '5', '8', '6', '8', '7', '8', '8', '8', '9',
|
||||
'9', '0', '9', '1', '9', '2', '9', '3', '9', '4', '9', '5', '9', '6', '9', '7', '9', '8', '9', '9'
|
||||
};
|
||||
return cDigitsLut;
|
||||
}
|
||||
|
||||
inline void WriteExponent(int K, char* buffer) {
|
||||
if (K < 0) {
|
||||
*buffer++ = '-';
|
||||
K = -K;
|
||||
}
|
||||
|
||||
if (K >= 100) {
|
||||
*buffer++ = '0' + static_cast<char>(K / 100);
|
||||
K %= 100;
|
||||
const char* d = GetDigitsLut() + K * 2;
|
||||
*buffer++ = d[0];
|
||||
*buffer++ = d[1];
|
||||
}
|
||||
else if (K >= 10) {
|
||||
const char* d = GetDigitsLut() + K * 2;
|
||||
*buffer++ = d[0];
|
||||
*buffer++ = d[1];
|
||||
}
|
||||
else
|
||||
*buffer++ = '0' + static_cast<char>(K);
|
||||
|
||||
*buffer = '\0';
|
||||
}
|
||||
|
||||
inline void Prettify(char* buffer, int length, int k) {
|
||||
const int kk = length + k; // 10^(kk-1) <= v < 10^kk
|
||||
|
||||
if (length <= kk && kk <= 21) {
|
||||
// 1234e7 -> 12340000000
|
||||
for (int i = length; i < kk; i++)
|
||||
buffer[i] = '0';
|
||||
buffer[kk] = '.';
|
||||
buffer[kk + 1] = '0';
|
||||
buffer[kk + 2] = '\0';
|
||||
}
|
||||
else if (0 < kk && kk <= 21) {
|
||||
// 1234e-2 -> 12.34
|
||||
memmove(&buffer[kk + 1], &buffer[kk], length - kk);
|
||||
buffer[kk] = '.';
|
||||
buffer[length + 1] = '\0';
|
||||
}
|
||||
else if (-6 < kk && kk <= 0) {
|
||||
// 1234e-6 -> 0.001234
|
||||
const int offset = 2 - kk;
|
||||
memmove(&buffer[offset], &buffer[0], length);
|
||||
buffer[0] = '0';
|
||||
buffer[1] = '.';
|
||||
for (int i = 2; i < offset; i++)
|
||||
buffer[i] = '0';
|
||||
buffer[length + offset] = '\0';
|
||||
}
|
||||
else if (length == 1) {
|
||||
// 1e30
|
||||
buffer[1] = 'e';
|
||||
WriteExponent(kk - 1, &buffer[2]);
|
||||
}
|
||||
else {
|
||||
// 1234e30 -> 1.234e33
|
||||
memmove(&buffer[2], &buffer[1], length - 1);
|
||||
buffer[1] = '.';
|
||||
buffer[length + 1] = 'e';
|
||||
WriteExponent(kk - 1, &buffer[0 + length + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
inline char* dtoa_milo(double value, char* buffer) {
|
||||
// Not handling NaN and inf
|
||||
assert(!isnan(value));
|
||||
assert(!isinf(value));
|
||||
|
||||
if (value == 0) {
|
||||
buffer[0] = '0';
|
||||
buffer[1] = '.';
|
||||
buffer[2] = '0';
|
||||
buffer[3] = '\0';
|
||||
}
|
||||
else {
|
||||
if (value < 0) {
|
||||
*buffer++ = '-';
|
||||
value = -value;
|
||||
}
|
||||
int length, K;
|
||||
Grisu2(value, buffer, &length, &K);
|
||||
Prettify(buffer, length, K);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
133
tests/ulib/eval_dtoa.cpp
Normal file
133
tests/ulib/eval_dtoa.cpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/**
|
||||
* eval_dtoa.cpp
|
||||
*
|
||||
* Testing dtoa...
|
||||
*/
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <ulib/string.h>
|
||||
#include "dtoa_milo.h"
|
||||
|
||||
#include "tsc.h"
|
||||
|
||||
#define N 100000
|
||||
|
||||
typedef void (*vPFdpc) (double,char*);
|
||||
|
||||
static void func_overhead(void* func, const char* name, int type)
|
||||
{
|
||||
int i;
|
||||
uint64_t t0, t1, tsc_overhead;
|
||||
uint64_t min, max, avg;
|
||||
uint64_t times[N];
|
||||
char a[32];
|
||||
|
||||
tsc_overhead = measure_tsc_overhead();
|
||||
|
||||
// we run N times and take the min
|
||||
for (i = 0; i < N; i++) {
|
||||
t0 = bench_start();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
((vPFdpc)func)(i,a);
|
||||
((vPFdpc)func)(i*10.01,a);
|
||||
((vPFdpc)func)(i*100.01,a);
|
||||
((vPFdpc)func)(i*1000.01,a);
|
||||
((vPFdpc)func)(i*10000.01,a);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
((vPFdpc)func)(-i,a);
|
||||
((vPFdpc)func)(-i*10.01,a);
|
||||
((vPFdpc)func)(-i*100.01,a);
|
||||
((vPFdpc)func)(-i*1000.01,a);
|
||||
((vPFdpc)func)(-i*10000.01,a);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
((vPFdpc)func)(i,a);
|
||||
((vPFdpc)func)(i*10.01,a);
|
||||
((vPFdpc)func)(i*100.01,a);
|
||||
((vPFdpc)func)(i*1000.01,a);
|
||||
((vPFdpc)func)(i*10000.01,a);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
((vPFdpc)func)(-i,a);
|
||||
((vPFdpc)func)(-i*10.01,a);
|
||||
((vPFdpc)func)(-i*100.01,a);
|
||||
((vPFdpc)func)(-i*1000.01,a);
|
||||
((vPFdpc)func)(-i*10000.01,a);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
t1 = bench_end();
|
||||
times[i] = t1 - t0 - tsc_overhead;
|
||||
}
|
||||
|
||||
min = ~0, max = 0, avg = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
avg += times[i];
|
||||
if (times[i] < min) { min = times[i]; }
|
||||
if (times[i] > max) { max = times[i]; }
|
||||
}
|
||||
avg /= N;
|
||||
|
||||
printf("\n- %s -\n", name);
|
||||
printf("Cost (min): %" PRIu64 " cycles\n", min);
|
||||
printf("Cost (avg): %" PRIu64 " cycles\n", avg);
|
||||
printf("Cost (max): %" PRIu64 " cycles\n", max);
|
||||
}
|
||||
|
||||
int
|
||||
U_EXPORT main(int argc, char* argv[])
|
||||
{
|
||||
U_ULIB_INIT(argv);
|
||||
|
||||
U_TRACE(5,"main(%d)",argc)
|
||||
|
||||
printf("=> Testing dtoa...\n");
|
||||
|
||||
/*
|
||||
char a[32], b[32];
|
||||
double sz1, sz2;
|
||||
|
||||
for (double i = DOUBLE_MIN; i < 0; ++i)
|
||||
{
|
||||
sz1 = sprintf(a, "%g", i);
|
||||
sz2 = u_dtoa(i, b);
|
||||
|
||||
if (sz1 != sz2 ||
|
||||
memcmp(a, b, sz1))
|
||||
{
|
||||
U_ERROR("sz1=%u sz2=%u a=%.*S b=%.*S", sz1, sz2, sz1, a, sz2, b)
|
||||
}
|
||||
}
|
||||
|
||||
for (double j = 0; j <= DOUBLE_MAX; ++j)
|
||||
{
|
||||
sz1 = sprintf(a, "%g", j);
|
||||
sz2 = u_dtoa(j, b);
|
||||
|
||||
if (sz1 != sz2 ||
|
||||
memcmp(a, b, sz1))
|
||||
{
|
||||
U_ERROR("sz1=%u sz2=%u a=%.*S b=%.*S", sz1, sz2, sz1, a, sz2, b)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func_overhead((void*)u_dtoa, "u_dtoa", 2);
|
||||
func_overhead((void*)dtoa_milo, "dtoa_milo", 2);
|
||||
|
||||
return 0;
|
||||
}
|
139
tests/ulib/eval_itoa.cpp
Normal file
139
tests/ulib/eval_itoa.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
/**
|
||||
* eval_itoa.cpp
|
||||
*
|
||||
* Testing itoa...
|
||||
*/
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <ulib/string.h>
|
||||
#include "branchlut.h"
|
||||
|
||||
#include "tsc.h"
|
||||
|
||||
#define N 100000
|
||||
|
||||
typedef void (*uPFi32pc) ( int32_t,char*);
|
||||
typedef void (*uPFi64pc) ( int64_t,char*);
|
||||
typedef void (*uPFu32pc) (uint32_t,char*);
|
||||
typedef void (*uPFu64pc) (uint64_t,char*);
|
||||
|
||||
static void func_overhead(void* func, const char* name, int type)
|
||||
{
|
||||
int i;
|
||||
uint64_t t0, t1, tsc_overhead;
|
||||
uint64_t min, max, avg;
|
||||
uint64_t times[N];
|
||||
char a[32];
|
||||
|
||||
tsc_overhead = measure_tsc_overhead();
|
||||
|
||||
// we run N times and take the min
|
||||
for (i = 0; i < N; i++) {
|
||||
t0 = bench_start();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
((uPFu32pc)func)(i,a);
|
||||
((uPFu32pc)func)(i*10,a);
|
||||
((uPFu32pc)func)(i*100,a);
|
||||
((uPFu32pc)func)(i*1000,a);
|
||||
((uPFu32pc)func)(i*10000,a);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
((uPFi32pc)func)(-i,a);
|
||||
((uPFi32pc)func)(-i*10,a);
|
||||
((uPFi32pc)func)(-i*100,a);
|
||||
((uPFi32pc)func)(-i*1000,a);
|
||||
((uPFi32pc)func)(-i*10000,a);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
((uPFu64pc)func)((uint64_t)i,a);
|
||||
((uPFu64pc)func)((uint64_t)i*10,a);
|
||||
((uPFu64pc)func)((uint64_t)i*100,a);
|
||||
((uPFu64pc)func)((uint64_t)i*1000,a);
|
||||
((uPFu64pc)func)((uint64_t)i*10000,a);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
{
|
||||
((uPFi64pc)func)((int64_t)-i,a);
|
||||
((uPFi64pc)func)((int64_t)-i*10,a);
|
||||
((uPFi64pc)func)((int64_t)-i*100,a);
|
||||
((uPFi64pc)func)((int64_t)-i*1000,a);
|
||||
((uPFi64pc)func)((int64_t)-i*10000,a);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
t1 = bench_end();
|
||||
times[i] = t1 - t0 - tsc_overhead;
|
||||
}
|
||||
|
||||
min = ~0, max = 0, avg = 0;
|
||||
for (i = 0; i < N; i++) {
|
||||
avg += times[i];
|
||||
if (times[i] < min) { min = times[i]; }
|
||||
if (times[i] > max) { max = times[i]; }
|
||||
}
|
||||
avg /= N;
|
||||
|
||||
printf("\n- %s -\n", name);
|
||||
printf("Cost (min): %" PRIu64 " cycles\n", min);
|
||||
printf("Cost (avg): %" PRIu64 " cycles\n", avg);
|
||||
printf("Cost (max): %" PRIu64 " cycles\n", max);
|
||||
}
|
||||
|
||||
int
|
||||
U_EXPORT main(int argc, char* argv[])
|
||||
{
|
||||
U_ULIB_INIT(argv);
|
||||
|
||||
U_TRACE(5,"main(%d)",argc)
|
||||
|
||||
printf("=> Testing itoa...\n");
|
||||
|
||||
/*
|
||||
char a[32], b[32];
|
||||
uint32_t sz1, sz2;
|
||||
|
||||
for (int64_t i = LLONG_MIN; i < 0; ++i)
|
||||
{
|
||||
sz1 = sprintf(a, "%lld", i);
|
||||
sz2 = u_num2str64s(i, b);
|
||||
|
||||
if (sz1 != sz2 ||
|
||||
memcmp(a, b, sz1))
|
||||
{
|
||||
U_ERROR("sz1=%u sz2=%u a=%.*S b=%.*S", sz1, sz2, sz1, a, sz2, b)
|
||||
}
|
||||
}
|
||||
|
||||
for (uint64_t j = 0; j <= LLONG_MAX; ++j)
|
||||
{
|
||||
sz1 = sprintf(a, "%llu", j);
|
||||
sz2 = u_num2str64(j, b);
|
||||
|
||||
if (sz1 != sz2 ||
|
||||
memcmp(a, b, sz1))
|
||||
{
|
||||
U_ERROR("sz1=%u sz2=%u a=%.*S b=%.*S", sz1, sz2, sz1, a, sz2, b)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func_overhead((void*)u_num2str32, "u_num2str32", 0);
|
||||
func_overhead((void*)u_num2str64, "u_num2str64", 2);
|
||||
|
||||
func_overhead((void*)u32toa_branchlut, "u32toa_branchlut", 0);
|
||||
func_overhead((void*)u64toa_branchlut, "u64toa_branchlut", 2);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -14,8 +14,9 @@ U_EXPORT main (int argc, char* argv[])
|
|||
|
||||
bool result;
|
||||
UIPAddress x;
|
||||
uint32_t addr;
|
||||
char address[16];
|
||||
UString name = UString(argv[1]), domain, name_domain, name_ret;
|
||||
UString tmp, name = UString(argv[1]), domain, name_domain, name_ret;
|
||||
|
||||
if (argv[2] &&
|
||||
argv[2][0])
|
||||
|
@ -30,14 +31,64 @@ U_EXPORT main (int argc, char* argv[])
|
|||
|
||||
U_ASSERT( result == false )
|
||||
|
||||
tmp = U_STRING_FROM_CONSTANT("127.0.0.1");
|
||||
|
||||
x.getBinaryForm(tmp, addr, true);
|
||||
|
||||
U_INTERNAL_DUMP("addr = %#08x %B", addr, addr)
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
U_INTERNAL_ASSERT( addr == 0x7f000001 )
|
||||
#else
|
||||
U_INTERNAL_ASSERT( addr == 0x0100007f )
|
||||
#endif
|
||||
|
||||
x.getBinaryForm(tmp, addr, false);
|
||||
|
||||
U_INTERNAL_DUMP("addr = %#08x %B", addr, addr)
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
U_INTERNAL_ASSERT( addr == 0x0100007f )
|
||||
#else
|
||||
U_INTERNAL_ASSERT( addr == 0x7f000001 )
|
||||
#endif
|
||||
|
||||
tmp = U_STRING_FROM_CONSTANT("255.255.255.255");
|
||||
|
||||
x.getBinaryForm(tmp, addr, true);
|
||||
|
||||
U_INTERNAL_DUMP("addr = %#08x %B", addr, addr)
|
||||
|
||||
U_INTERNAL_ASSERT( addr == 0xffffffff )
|
||||
|
||||
x.getBinaryForm(tmp, addr, false);
|
||||
|
||||
U_INTERNAL_DUMP("addr = %#08x %B", addr, addr)
|
||||
|
||||
U_INTERNAL_ASSERT( addr == 0xffffffff )
|
||||
|
||||
tmp = U_STRING_FROM_CONSTANT("255.0.0.255");
|
||||
|
||||
x.getBinaryForm(tmp, addr, true);
|
||||
|
||||
U_INTERNAL_DUMP("addr = %#08x %B", addr, addr)
|
||||
|
||||
U_INTERNAL_ASSERT( addr == 0xff0000ff )
|
||||
|
||||
x.getBinaryForm(tmp, addr, false);
|
||||
|
||||
U_INTERNAL_DUMP("addr = %#08x %B", addr, addr)
|
||||
|
||||
U_INTERNAL_ASSERT( addr == 0xff0000ff )
|
||||
|
||||
// Test code for matching IP masks
|
||||
|
||||
UIPAllow a;
|
||||
|
||||
U_ASSERT( a.parseMask(U_STRING_FROM_CONSTANT("127.0.0.5")) == true )
|
||||
|
||||
// 127.0.0.5
|
||||
|
||||
U_ASSERT( a.parseMask(U_STRING_FROM_CONSTANT("127.0.0.5")) == true )
|
||||
|
||||
x.setHostName(U_STRING_FROM_CONSTANT("127.0.0.5"));
|
||||
|
||||
U_ASSERT( a.isAllowed(x.getInAddr()) == true )
|
||||
|
@ -142,7 +193,7 @@ U_EXPORT main (int argc, char* argv[])
|
|||
|
||||
U_INTERNAL_ASSERT_EQUALS(n, 2)
|
||||
|
||||
n = UIPAllow::find("192.168.253.253", vipallow);
|
||||
n = UIPAllow::find(U_STRING_FROM_CONSTANT("192.168.253.253"), vipallow);
|
||||
|
||||
U_INTERNAL_ASSERT( n != U_NOT_FOUND )
|
||||
|
||||
|
|
113
tests/ulib/tsc.h
Normal file
113
tests/ulib/tsc.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
// Support for using the TSC register on intel machines as a timing method.
|
||||
//
|
||||
// Should compile with -O to ensure inline attribute is honoured.
|
||||
//
|
||||
|
||||
#ifndef __TSC_HDR
|
||||
#define __TSC_HDR
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define TSC_OVERHEAD_N 100000
|
||||
|
||||
static inline void _sync_tsc(void)
|
||||
{
|
||||
asm volatile("cpuid" : : : "%rax", "%rbx", "%rcx", "%rdx");
|
||||
}
|
||||
|
||||
static inline uint64_t _rdtsc(void)
|
||||
{
|
||||
unsigned a, d;
|
||||
asm volatile("rdtsc" : "=a" (a), "=d" (d) : : "%rbx", "%rcx");
|
||||
return ((uint64_t) a) | (((uint64_t) d) << 32);
|
||||
}
|
||||
|
||||
static inline uint64_t _rdtscp(void)
|
||||
{
|
||||
unsigned a, d;
|
||||
asm volatile("rdtscp" : "=a" (a), "=d" (d) : : "%rbx", "%rcx");
|
||||
return ((uint64_t) a) | (((uint64_t) d) << 32);
|
||||
}
|
||||
|
||||
static inline uint64_t bench_start(void)
|
||||
{
|
||||
// unsigned cycles_low, cycles_high;
|
||||
// uint64_t t;
|
||||
//
|
||||
// asm volatile( "CPUID\n\t" // serialize
|
||||
// "RDTSC\n\t" // read clock
|
||||
// "mov %%edx, %0\n\t"
|
||||
// "mov %%eax, %1\n\t"
|
||||
// : "=r" (cycles_high), "=r" (cycles_low)
|
||||
// :: "%rax", "%rbx", "%rcx", "%rdx" );
|
||||
// return ((uint64_t) cycles_high << 32) | cycles_low;
|
||||
|
||||
_sync_tsc();
|
||||
return _rdtsc();
|
||||
}
|
||||
|
||||
static inline uint64_t bench_end(void)
|
||||
{
|
||||
// unsigned cycles_low, cycles_high;
|
||||
// uint64_t t;
|
||||
//
|
||||
// asm volatile( "RDTSCP\n\t" // read clock + serialize
|
||||
// "mov %%edx, %0\n\t"
|
||||
// "mov %%eax, %1\n\t"
|
||||
// "CPUID\n\t" // serialze -- but outside clock region!
|
||||
// : "=r" (cycles_high), "=r" (cycles_low)
|
||||
// :: "%rax", "%rbx", "%rcx", "%rdx" );
|
||||
// return ((uint64_t) cycles_high << 32) | cycles_low;
|
||||
|
||||
uint64_t t = _rdtscp();
|
||||
_sync_tsc();
|
||||
return t;
|
||||
}
|
||||
|
||||
static uint64_t measure_tsc_overhead(void)
|
||||
{
|
||||
uint64_t t0, t1, overhead = ~0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < TSC_OVERHEAD_N; i++) {
|
||||
t0 = bench_start();
|
||||
asm volatile("");
|
||||
t1 = bench_end();
|
||||
if (t1 - t0 < overhead)
|
||||
overhead = t1 - t0;
|
||||
}
|
||||
|
||||
return overhead;
|
||||
}
|
||||
|
||||
/*
|
||||
# TSC Frequency
|
||||
To convert from cycles to wall-clock time we need to know TSC frequency
|
||||
Frequency scaling on modern Intel chips doesn't affect the TSC.
|
||||
|
||||
Sadly, there doesn't seem to be a good way to do this.
|
||||
|
||||
# Intel V3B: 17.14
|
||||
That rate may be set by the maximum core-clock to bus-clock ratio of the
|
||||
processor or may be set by the maximum resolved frequency at which the
|
||||
processor is booted. The maximum resolved frequency may differ from the
|
||||
processor base frequency, see Section 18.15.5 for more detail. On certain
|
||||
processors, the TSC frequency may not be the same as the frequency in the brand
|
||||
string.
|
||||
|
||||
# Linux Source
|
||||
http://lxr.free-electrons.com/source/arch/x86/kernel/tsc.c?v=2.6.31#L399
|
||||
|
||||
Linux runs a calibration phase where it uses some hardware timers and checks
|
||||
how many TSC cycles occur in 50ms.
|
||||
*/
|
||||
#define TSC_FREQ_MHZ 3500
|
||||
|
||||
static inline uint64_t cycles_to_ns(uint64_t cycles)
|
||||
{
|
||||
// XXX: This is not safe! We don't have a good cross-platform way to
|
||||
// determine the TSC frequency for some strange reason.
|
||||
return cycles * 1000 / TSC_FREQ_MHZ;
|
||||
}
|
||||
|
||||
#endif /* __TSC_HDR */
|
Loading…
Reference in New Issue
Block a user