From 1757dd9f6e0211bec29c4ce0fb498dde6aa78e7e Mon Sep 17 00:00:00 2001 From: "Costa Tsaousis (ktsaou)" Date: Wed, 18 Jan 2017 01:51:13 +0200 Subject: [PATCH] use gcc statement expressions to inline commonly used functions --- CMakeLists.txt | 4 +- configure.ac | 1 + m4/ax_c_statement_expressions.m4 | 23 ++++++++++ src/Makefile.am | 2 + src/common.c | 22 ++-------- src/common.h | 6 +-- src/inlined.h | 75 ++++++++++++++++++++++++++++++++ 7 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 m4/ax_c_statement_expressions.m4 create mode 100644 src/inlined.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b9ae6a62..4daf76cb 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -101,7 +101,7 @@ set(NETDATA_SOURCE_FILES src/registry_person.c src/registry_person.h src/registry_machine.c - src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c src/proc_uptime.c src/sys_devices_system_edac_mc.c src/plugin_proc_diskspace.c src/plugin_proc_diskspace.h src/simple_pattern.c src/simple_pattern.h) + src/registry_machine.h src/registry_internals.c src/registry_init.c src/registry_db.c src/registry_log.c src/proc_uptime.c src/sys_devices_system_edac_mc.c src/plugin_proc_diskspace.c src/plugin_proc_diskspace.h src/simple_pattern.c src/simple_pattern.h src/inlined.h) set(APPS_PLUGIN_SOURCE_FILES src/appconfig.c @@ -126,5 +126,5 @@ add_definitions(-DHAVE_CONFIG_H -DCACHE_DIR="/var/cache/netdata" -DCONFIG_DIR="/ add_executable(netdata ${NETDATA_SOURCE_FILES}) target_link_libraries (netdata m z uuid ${CMAKE_THREAD_LIBS_INIT}) -add_executable(apps.plugin ${APPS_PLUGIN_SOURCE_FILES}) +add_executable(apps.plugin ${APPS_PLUGIN_SOURCE_FILES} src/inlined.h) target_link_libraries (apps.plugin m ${CMAKE_THREAD_LIBS_INIT}) diff --git a/configure.ac b/configure.ac index 87242794..002a3aa5 100644 --- a/configure.ac +++ b/configure.ac @@ -129,6 +129,7 @@ AC_C_INLINE AC_FUNC_STRERROR_R AC_C__GENERIC AC_C___ATOMIC +AC_C_STMT_EXPR AC_CHECK_SIZEOF([void *]) AC_CANONICAL_HOST AC_HEADER_MAJOR diff --git a/m4/ax_c_statement_expressions.m4 b/m4/ax_c_statement_expressions.m4 new file mode 100644 index 00000000..fb259e72 --- /dev/null +++ b/m4/ax_c_statement_expressions.m4 @@ -0,0 +1,23 @@ +# AC_C_STMT_EXPR +# ------------- +# Define HAVE_STMT_EXPR if compiler has statement expressions. +AN_IDENTIFIER([_Generic], [AC_C_STMT_EXPR]) +AC_DEFUN([AC_C_STMT_EXPR], +[AC_CACHE_CHECK([for statement expressions], ac_cv_c_stmt_expr, +[AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[int + main (int argc, char **argv) + { + int x = ({ int y = 1; y; }); + return x; + } + ]])], + [ac_cv_c_stmt_expr=yes], + [ac_cv_c_stmt_expr=no])]) +if test $ac_cv_c_stmt_expr = yes; then + AC_DEFINE([HAVE_STMT_EXPR], 1, + [Define to 1 if compiler supports statement expressions.]) +fi +])# AC_C_STMT_EXPR + diff --git a/src/Makefile.am b/src/Makefile.am index 264e58df..d7adc7c2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,6 +37,7 @@ netdata_SOURCES = \ eval.c eval.h \ global_statistics.c global_statistics.h \ health.c health.h \ + inlined.h \ log.c log.h \ main.c main.h \ plugin_checks.c plugin_checks.h \ @@ -124,6 +125,7 @@ apps_plugin_SOURCES = \ avl.c avl.h \ clocks.c clocks.h \ common.c common.h \ + inlined.h \ log.c log.h \ procfile.c procfile.h \ web_buffer.c web_buffer.h \ diff --git a/src/common.c b/src/common.c index 36fa0c9b..28ba7259 100644 --- a/src/common.c +++ b/src/common.c @@ -807,7 +807,7 @@ uint32_t simple_hash(const char *name) } */ - +/* // http://isthe.com/chongo/tech/comp/fnv/#FNV-1a uint32_t simple_hash(const char *name) { unsigned char *s = (unsigned char *) name; @@ -842,6 +842,7 @@ uint32_t simple_uhash(const char *name) { } return hval; } +*/ /* // http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx @@ -1165,25 +1166,8 @@ void get_system_HZ(void) { long ticks; if ((ticks = sysconf(_SC_CLK_TCK)) == -1) { - perror("sysconf"); + error("Cannot get system clock ticks"); } hz = (unsigned int) ticks; } - -int read_single_number_file(const char *filename, unsigned long long *result) { - char buffer[1024 + 1]; - - int fd = open(filename, O_RDONLY, 0666); - if(unlikely(fd == -1)) return 1; - - ssize_t r = read(fd, buffer, 1024); - if(unlikely(r == -1)) { - close(fd); - return 2; - } - - close(fd); - *result = strtoull(buffer, NULL, 0); - return 0; -} diff --git a/src/common.h b/src/common.h index 9e9cc8fc..26ad467d 100644 --- a/src/common.h +++ b/src/common.h @@ -207,13 +207,11 @@ #include "unit_test.h" #include "ipc.h" #include "backends.h" +#include "inlined.h" extern void netdata_fix_chart_id(char *s); extern void netdata_fix_chart_name(char *s); -extern uint32_t simple_hash(const char *name); -extern uint32_t simple_uhash(const char *name); - extern void strreverse(char* begin, char* end); extern char *mystrsep(char **ptr, char *s); extern char *trim(char *s); @@ -277,6 +275,4 @@ extern void get_system_HZ(void); #endif #endif -extern int read_single_number_file(const char *filename, unsigned long long *result); - #endif /* NETDATA_COMMON_H */ diff --git a/src/inlined.h b/src/inlined.h new file mode 100644 index 00000000..87a54dda --- /dev/null +++ b/src/inlined.h @@ -0,0 +1,75 @@ +#ifndef NETDATA_INLINED_H +#define NETDATA_INLINED_H + +#include "common.h" + +#ifdef HAVE_STMT_EXPR +// GCC extension to define a function as a preprocessor macro + +#define simple_hash(name) ({ \ + register unsigned char *__hash_source = (unsigned char *)(name); \ + register uint32_t __hash_value = 0x811c9dc5; \ + while (*__hash_source) { \ + __hash_value *= 16777619; \ + __hash_value ^= (uint32_t) *__hash_source++; \ + } \ + __hash_value; \ +}) + +#define simple_uhash(name) ({ \ + register unsigned char *__hash_source = (unsigned char *)(name); \ + register uint32_t __hash_value = 0x811c9dc5, __hash_char; \ + while ((__hash_char = *__hash_source++)) { \ + if (unlikely(__hash_char >= 'A' && __hash_char <= 'Z')) \ + __hash_char += 'a' - 'A'; \ + __hash_value *= 16777619; \ + __hash_value ^= __hash_char; \ + } \ + __hash_value; \ +}) + +#else /* ! HAVE_STMT_EXPR */ + +// for faster execution, allow the compiler to inline +// these functions that are called to hash strings +static inline uint32_t simple_hash(const char *name) { + register unsigned char *s = (unsigned char *) name; + register uint32_t hval = 0x811c9dc5; + while (*s) { + hval *= 16777619; + hval ^= (uint32_t) *s++; + } + return hval; +} + +static inline uint32_t simple_uhash(const char *name) { + register unsigned char *s = (unsigned char *) name; + register uint32_t hval = 0x811c9dc5, c; + while ((c = *s++)) { + if (unlikely(c >= 'A' && c <= 'Z')) c += 'a' - 'A'; + hval *= 16777619; + hval ^= c; + } + return hval; +} + +#endif /* HAVE_STMT_EXPR */ + +static inline int read_single_number_file(const char *filename, unsigned long long *result) { + char buffer[1024 + 1]; + + int fd = open(filename, O_RDONLY, 0666); + if(unlikely(fd == -1)) return 1; + + ssize_t r = read(fd, buffer, 1024); + if(unlikely(r == -1)) { + close(fd); + return 2; + } + + close(fd); + *result = strtoull(buffer, NULL, 0); + return 0; +} + +#endif //NETDATA_INLINED_H -- 2.39.2