]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #135 in SNORT/snort3 from ~JOCORNET/snort3:mem_profiler to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 17 Nov 2015 22:41:02 +0000 (17:41 -0500)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Tue, 17 Nov 2015 22:41:02 +0000 (17:41 -0500)
Squashed commit of the following:

commit 3b843fdc2a341e22d63840d72900d90767df31c9
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Tue Nov 17 15:56:43 2015 -0500

    hardened PERF_PROFILING

commit 6eb3d6f8ab4d474344c5ff2143206f23e9c96aa4
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Tue Nov 17 13:47:30 2015 -0500

    fixed typo

commit 45c6d8816b00fdf793704e733f20c0f0d863708e
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Mon Nov 16 18:03:38 2015 -0500

    updated profiler unit tests

commit 6a6bb3900277062d25b2c06b9c5cd9b246e09b68
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Mon Nov 16 17:00:45 2015 -0500

    fluff

commit ef2a51bcff9e5f59bd6087ad4356c1f64c5fa23a
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Mon Nov 16 16:53:34 2015 -0500

    updates

commit 8f3563c3b3f2e6df894aa98d25390cd1f5c602d0
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Mon Nov 16 15:47:33 2015 -0500

    added clock type definitions

commit a426b1be454df278cefd65cf25f59af6247e57e2
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Mon Nov 16 15:43:53 2015 -0500

    partial commit converted ticks to use high_resolution_clock duration

commit ad22683e444641f954e57de6194174e5add8305f
Author: Joel Cornett <joel.cornett@gmail.com>
Date:   Mon Nov 16 15:40:25 2015 -0500

    partial commit, updated build system in preparation for memory profiling

42 files changed:
cmake/configure_options.cmake
cmake/create_options.cmake
config.cmake.h.in
configure.ac
configure_cmake.sh
src/CMakeLists.txt
src/Makefile.am
src/detection/detect.cc
src/detection/detect.h
src/detection/detection_options.cc
src/detection/detection_options.h
src/detection/fp_detect.cc
src/detection/fp_detect.h
src/detection/treenodes.h
src/framework/mpse.cc
src/framework/mpse.h
src/ips_options/ips_http.cc
src/main/modules.cc
src/main/snort.cc
src/main/snort_config.cc
src/main/snort_config.h
src/managers/codec_manager.h
src/managers/module_manager.cc
src/ppm/ppm.h
src/profiler/CMakeLists.txt
src/profiler/Makefile.am
src/profiler/profiler.cc
src/profiler/profiler.h
src/protocols/packet_manager.cc
src/service_inspectors/ftp_telnet/ft_main.cc
src/service_inspectors/ftp_telnet/ft_main.h
src/service_inspectors/ftp_telnet/ftp.cc
src/service_inspectors/ftp_telnet/telnet.cc
src/service_inspectors/http_inspect/hi_main.cc
src/service_inspectors/http_inspect/hi_main.h
src/service_inspectors/http_inspect/http_inspect.cc
src/time/CMakeLists.txt
src/time/Makefile.am
src/time/clock_defs.h [new file with mode: 0644]
src/time/dev_notes.txt
src/time/stopwatch.h [new file with mode: 0644]
src/utils/stats.cc

index 232faad8d5c2b9163ceceae3c1b7dcb41e2eaac1..5dbb9192ad06a2aa91224dd42c04f70478fc0f13 100644 (file)
@@ -7,7 +7,6 @@
 
 # convert cmake options into compiler defines
 
-set_project_compiler_defines_if_true (ENABLE_PERFPROFILING "PERF_PROFILING")
 set_project_compiler_defines_if_true (ENABLE_DEBUG_MSGS "DEBUG_MSGS")
 set_project_compiler_defines_if_true (ENABLE_DEBUG "DEBUG")
 set_project_compiler_defines_if_true (BUILD_HA "ENABLE_HA")
@@ -28,7 +27,6 @@ set_if_true (STATIC_CODECS STATIC_CODECS)
 set_if_true (ENABLE_VALGRIND VALGRIND_TESTING)
 set_if_true (ENABLE_PPM PPM_MGR)
 set_if_true (ENABLE_PPM_TEST PPM_TEST)
-set_if_true (ENABLE_PERFPROFILING PERF_PROFILING)
 set_if_true (BUILD_HA ENABLE_HA )
 set_if_true (ENABLE_LINUX_SMP_STATS LINUX_SMP)
 set_if_true (ENABLE_DEBUG DEBUG)
index 7d2bc5f967760e30cfe7e8d3d1bf1286ad89cc9c..18600d20e4feac6ef6623f529f71e30e32c4bb6f 100644 (file)
@@ -14,7 +14,6 @@ option (STATIC_SEARCH_ENGINES "include search engines in binary" ON)
 option (ENABLE_STATIC_DAQ "Link static DAQ modules" ON)
 option (ENABLE_VALGRIND "Only use if you are testing with valgrind" OFF)
 option (ENABLE_PPM "Disable packet/rule performance monitor" OFF)
-option (ENABLE_PERFPROFILING "Disable preprocessor and rule performance profiling" OFF)
 option (ENABLE_LINUX_SMP_STATS "Enable statistics reporting through proc" OFF)
 option (ENABLE_PTHREAD "Disable pthread support" ON)
 option (ENABLE_DEBUG_MSGS "Enable debug printing options (bugreports and developers only)" OFF)
index 1243cd00045b749214bee1ac7a9e6bba8029a980..e937d313533f64c1dcb8818b2e22314f6076c51e 100644 (file)
@@ -57,9 +57,6 @@
 /* build ppm manager for readback */
 #cmakedefine PPM_TEST 1
 
-/* enable profiling */
-#cmakedefine PERF_PROFILING 1
-
 /* enable proc stats */
 #cmakedefine LINUX_SMP 1
 
index 92c97b0cbc2d05ff282666523419243a68f25ed6..d7a26e02a4f3ee2abf43072fb7b55ad6b9332170 100644 (file)
@@ -18,7 +18,7 @@
 # if you add an AC_DEFINE() for a symbol that appears in an exported
 # header, you must also add that symbol to CPPFLAGS.  This ensures that
 # external modules like those in examples can use pkg-config to get the
-# same symbols Snort did.  See PERF_PROFILING for an example.
+# same symbols Snort did.  See PPM for an example.
 #--------------------------------------------------------------------------
 # initialization
 #--------------------------------------------------------------------------
@@ -350,17 +350,6 @@ if test "x$enable_ppm" = "xyes"; then
     AC_DEFINE(PPM_MGR, [1], [build ppm manager])
 fi
 
-AC_ARG_ENABLE(perf-profiling,
-    AC_HELP_STRING([--enable-perf-profiling],[enable module and rule performance profiling]),
-    enable_perf_profiling="$enableval", enable_perf_profiling="no")
-
-AM_CONDITIONAL(PERF_PROFILING, test "x$enable_perf_profiling" = "xyes")
-
-if test "x$enable_perf_profiling" = "xyes"; then
-    CPPFLAGS="$CPPFLAGS -DPERF_PROFILING"
-    AC_DEFINE(PERF_PROFILING, [1], [enable perf profiling])
-fi
-
 AC_ARG_ENABLE(shell,
     AC_HELP_STRING([--enable-shell],[enable command line shell support]),
     enable_shell="$enableval", enable_shell="no")
index 1c3d7dd359c2f12a0a134d51c9609fca23fa35f5..e54b89b778ed5d4e9feafb5af5147c8bb2f4fffc 100755 (executable)
@@ -32,7 +32,6 @@ Optional Features:
     --disable-static-piglets   do not include piglets in binary
     --enable-valgrind        Only use if you are testing with valgrind.
     --enable-ppm            Enable packet/rule performance monitor
-    --enable-perf-profiling  Enable preprocessor and rule performance profiling
     --enable-shell           enable command line shell support
     --enable-linux-smp-stats Enable statistics reporting through proc
     --enable-debug-msgs      Enable debug printing options (bugreports and developers only)
@@ -199,12 +198,6 @@ while [ $# -ne 0 ]; do
         --enable-ppm)
             append_cache_entry ENABLE_PPM    BOOL   true
             ;;
-        --disable-perf-profiling)
-            append_cache_entry ENABLE_PERFPROFILING    BOOL   false
-            ;;
-        --enable-perf-profiling)
-            append_cache_entry ENABLE_PERFPROFILING    BOOL   true
-            ;;
         --disable-linux-smp-stats)
             append_cache_entry ENABLE_LINUX_SMP_STATS    BOOL   false
             ;;
index aa0aae10b139f1a086cc42a33da33467387c396e..5ec0481dc14db70958313d50f8ad1575496dd2e5 100644 (file)
@@ -79,10 +79,6 @@ if (ENABLE_PPM)
     add_subdirectory(ppm)
 endif (ENABLE_PPM)
 
-if (ENABLE_PERFPROFILING)
-    set(PERFPROFILING_LIBRARIES profiler)
-endif (ENABLE_PERFPROFILING)
-
 #  The main Snort executableRA
 add_executable( snort
     main.h
@@ -133,7 +129,7 @@ target_link_libraries( snort
     framework
     time
     ${PPM_LIBRARIES}
-    ${PERFPROFILING_LIBRARIES}
+    profiler
     ips_actions
     events
     hash
index 468d65d12b154e617e0eb84bcb709e204b0a1d4b..6de33c6241e556cb94c9daac6fa067042aada05c 100644 (file)
@@ -40,10 +40,6 @@ if PPM_MGR
 ppm_list = ppm/libppm.a
 endif
 
-if PERF_PROFILING
-profiler_list = profiler/libprofiler.a
-endif
-
 snort_LDFLAGS = -export-dynamic
 
 # order libs to avoid undefined symbols
@@ -94,7 +90,7 @@ detection/libdetection.a \
 framework/libframework.a \
 time/libtime.a \
 $(ppm_list) \
-$(profiler_list) \
+profiler/libprofiler.a \
 actions/libips_actions.a \
 events/libevents.a \
 hash/libhash.a \
index 734f7a7e979b881e48d2c433cf938586ba6b31e5..dc0bb65624cfaf720e56d56c4b6bf3ecd0535ee6 100644 (file)
 #define CHECK_SRC_PORT       0x08
 #define CHECK_DST_PORT       0x10
 
-#ifdef PERF_PROFILING
 THREAD_LOCAL ProfileStats detectPerfStats;
 THREAD_LOCAL ProfileStats eventqPerfStats;
 THREAD_LOCAL ProfileStats rebuiltPacketPerfStats;
-#endif
 
 THREAD_LOCAL int do_detect;
 THREAD_LOCAL int do_detect_content;
index 5b7a75ee0807d0fa63d31b7f52b2019faa9b76a8..f054b4ecac5b06ec93d1df3afe36b19c1ff691b3 100644 (file)
 #include "log/log.h"
 #include "events/event.h"
 
+struct ProfileStats;
+
 extern SO_PUBLIC THREAD_LOCAL int do_detect;
 extern SO_PUBLIC THREAD_LOCAL int do_detect_content;
 
-#ifdef PERF_PROFILING
-struct ProfileStats;
 extern THREAD_LOCAL ProfileStats eventqPerfStats;
 extern THREAD_LOCAL ProfileStats detectPerfStats;
 extern THREAD_LOCAL ProfileStats rebuiltPacketPerfStats;
-#endif
 
 // main loop hooks
 void snort_ignore(Packet*);
index c1df6a9b96657c8d8b6f3c74ffc4dd61cf66e8f1..a1c587155772e0b1bee83f10ada8cb3e8e00e986 100644 (file)
@@ -386,10 +386,8 @@ int detection_option_node_evaluate(
 
     dot_node_state_t* state = node->state + get_instance_id();
 
-#ifdef PERF_PROFILING
     auto& node_stats = *state;
     NODE_PERF_PROFILE(node_stats);
-#endif
 
     int result = 0;
     int rval = DETECTION_OPTION_NO_MATCH;
@@ -512,10 +510,8 @@ int detection_option_node_evaluate(
 
                 if ( f_result )
                 {
-#ifdef PERF_PROFILING
-                    if (PROFILING_RULES)
-                        otn->state[get_instance_id()].matches++;
-#endif
+                    otn->state[get_instance_id()].matches++;
+
                     if ( !eval_data->flowbit_noalert )
                         fpAddMatch((OTNX_MATCH_DATA*)pomd, pattern_size, otn);
 
@@ -611,10 +607,10 @@ int detection_option_node_evaluate(
             {
                 // bail if we exceeded time
 
-#ifdef PERF_PROFILING
+                // FIXIT-M J this is unconditional (match or no match) since this
+                // block is guaranteed to return
                 if ( result != DETECTION_OPTION_NO_MATCH )
                     NODE_PERF_PROFILE_STOP_MATCH(node_stats);
-#endif
 
                 state->last_check.result = result;
                 return result;
@@ -743,12 +739,10 @@ int detection_option_node_evaluate(
         else
             continue_loop = false;
 
-#ifdef PERF_PROFILING
         // We're essentially checking this node again and it potentially
         // might match again
-        if ( continue_loop && PROFILING_RULES )
+        if ( continue_loop )
             state->checks++;
-#endif
 
         loop_count++;
     }
@@ -780,42 +774,42 @@ int detection_option_node_evaluate(
     return result;
 }
 
-#ifdef PERF_PROFILING
-typedef struct node_profile_stats
+struct node_profile_stats
 {
-    uint64_t ticks;
-    uint64_t ticks_match;
-    uint64_t ticks_no_match;
+    // FIXIT-L J should be use factored out field from dot_node_state_t
+    hr_duration elapsed;
+    hr_duration elapsed_match;
+    hr_duration elapsed_no_match;
     uint64_t checks;
     uint64_t disables;
-} node_profile_stats_t;
+};
 
 static void detection_option_node_update_otn_stats(
     detection_option_tree_node_t* node,
-    node_profile_stats_t* stats, uint64_t checks
+    node_profile_stats* stats, uint64_t checks
 #ifdef PPM_MGR
     , uint64_t disables
 #endif
     )
 {
     int i;
-    node_profile_stats_t local_stats; /* cumulative stats for this node */
-    node_profile_stats_t node_stats;  /* sum of all instances */
+    node_profile_stats local_stats; /* cumulative stats for this node */
+    node_profile_stats node_stats;  /* sum of all instances */
 
     memset(&node_stats, 0, sizeof(node_stats));
 
     for ( unsigned i = 0; i < get_instance_max(); ++i )
     {
-        node_stats.ticks += node->state[i].ticks;
-        node_stats.ticks_match += node->state[i].ticks_match;
-        node_stats.ticks_no_match += node->state[i].ticks_no_match;
+        node_stats.elapsed += node->state[i].elapsed;
+        node_stats.elapsed_match += node->state[i].elapsed_match;
+        node_stats.elapsed_no_match += node->state[i].elapsed_no_match;
         node_stats.checks += node->state[i].checks;
     }
     if (stats)
     {
-        local_stats.ticks = stats->ticks + node_stats.ticks;
-        local_stats.ticks_match = stats->ticks_match + node_stats.ticks_match;
-        local_stats.ticks_no_match = stats->ticks_no_match + node_stats.ticks_no_match;
+        local_stats.elapsed = stats->elapsed + node_stats.elapsed;
+        local_stats.elapsed_match = stats->elapsed_match + node_stats.elapsed_match;
+        local_stats.elapsed_no_match = stats->elapsed_no_match + node_stats.elapsed_no_match;
         if (node_stats.checks > stats->checks)
             local_stats.checks = node_stats.checks;
         else
@@ -826,9 +820,9 @@ static void detection_option_node_update_otn_stats(
     }
     else
     {
-        local_stats.ticks = node_stats.ticks;
-        local_stats.ticks_match = node_stats.ticks_match;
-        local_stats.ticks_no_match = node_stats.ticks_no_match;
+        local_stats.elapsed = node_stats.elapsed;
+        local_stats.elapsed_match = node_stats.elapsed_match;
+        local_stats.elapsed_no_match = node_stats.elapsed_no_match;
         local_stats.checks = node_stats.checks;
 #ifdef PPM_MGR
         local_stats.disables = disables;
@@ -841,9 +835,9 @@ static void detection_option_node_update_otn_stats(
         // FIXIT-M should be sum of instances (only called from main thread)
         OptTreeNode* otn = (OptTreeNode*)node->option_data;
         OtnState* state = otn->state + get_instance_id();
-        state->ticks += local_stats.ticks;
-        state->ticks_match += local_stats.ticks_match;
-        state->ticks_no_match += local_stats.ticks_no_match;
+        state->elapsed += local_stats.elapsed;
+        state->elapsed_match += local_stats.elapsed_match;
+        state->elapsed_no_match += local_stats.elapsed_no_match;
         if (local_stats.checks > state->checks)
             state->checks = local_stats.checks;
 #ifdef PPM_MGR
@@ -904,7 +898,6 @@ void detection_option_tree_update_otn_stats(SFXHASH* doth)
     }
 }
 
-#endif
 
 detection_option_tree_root_t* new_root()
 {
index f0ad3b1d111901908c24a4936752dba0cbb285b2..6d49a9e6cc3b415b59f2f45e059d2ba4c4f62c43 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/time.h>
 #include "main/snort_types.h"
 #include "detection/rule_option_types.h"
+#include "time/clock_defs.h"
 
 struct Packet;
 struct SFXHASH;
@@ -57,31 +58,30 @@ struct dot_node_state_t
         char flowbit_failed;
     } last_check;
 
-#ifdef PERF_PROFILING
-    uint64_t ticks;
-    uint64_t ticks_match;
-    uint64_t ticks_no_match;
+    // FIXIT-L J perf profiler stuff should be factored of the node state struct
+    hr_duration elapsed;
+    hr_duration elapsed_match;
+    hr_duration elapsed_no_match;
     uint64_t checks;
     uint64_t disables;
-#endif
+
 #ifdef PPM_MGR
     uint64_t ppm_disable_cnt;
     uint64_t ppm_enable_cnt;
 #endif
 
-#ifdef PERF_PROFILING
-    void update(uint64_t elapsed, bool match)
+    // FIXIT-L J perf profiler stuff should be factored of the node state struct
+    void update(hr_duration delta, bool match)
     {
-        ticks += elapsed;
+        elapsed += delta;;
 
         if ( match )
-            ticks_match += elapsed;
+            elapsed_match += delta;
         else
-            ticks_no_match += elapsed;
+            elapsed_no_match += delta;
 
         ++checks;
     }
-#endif
 };
 
 struct detection_option_tree_node_t
@@ -138,9 +138,7 @@ void DetectionTreeHashTableFree(SFXHASH*);
 #ifdef DEBUG_OPTION_TREE
 void print_option_tree(detection_option_tree_node_t* node, int level);
 #endif
-#ifdef PERF_PROFILING
 void detection_option_tree_update_otn_stats(SFXHASH*);
-#endif
 
 detection_option_tree_root_t* new_root();
 void free_detection_option_root(void** existing_tree);
index ecfc29c24ec38829a29e9ba7f1ea48e03bff0332..6718002bc533567dae7b4d094086c370bc8c2867 100644 (file)
 #include "protocols/udp.h"
 #include "protocols/icmp4.h"
 
-#ifdef PERF_PROFILING
 THREAD_LOCAL ProfileStats rulePerfStats;
 THREAD_LOCAL ProfileStats ruleRTNEvalPerfStats;
 THREAD_LOCAL ProfileStats ruleOTNEvalPerfStats;
 THREAD_LOCAL ProfileStats ruleNFPEvalPerfStats;
-#endif
 
 THREAD_LOCAL uint64_t rule_eval_pkt_count = 0;
 
@@ -246,9 +244,7 @@ int fpLogEvent(const RuleTreeNode* rtn, const OptTreeNode* otn, Packet* p)
         return 1;
     }
 
-#ifdef PERF_PROFILING
     otn->state[get_instance_id()].alerts++;
-#endif
 
     event_id++;
     action_execute((RuleType)action, p, otn, event_id);
index 477bee25e737381ced300df83004548a4cebef36..783fb084d358746a52624dd71ea2799f17c2a238 100644 (file)
 
 #define REBUILD_FLAGS (PKT_REBUILT_FRAG | PKT_REBUILT_STREAM)
 
-#ifdef PERF_PROFILING
 struct ProfileStats;
+
 extern THREAD_LOCAL ProfileStats rulePerfStats;
 extern THREAD_LOCAL ProfileStats ruleRTNEvalPerfStats;
 extern THREAD_LOCAL ProfileStats ruleOTNEvalPerfStats;
 extern THREAD_LOCAL ProfileStats ruleNFPEvalPerfStats;
-#endif
 
 /*
 **  This is the only function that is needed to do an
index eb77ca0c45893b121835942a4497cc7fc898f701..b4eef194cd72709a3b85d83ed6f3dcf4eb07c2e7 100644 (file)
@@ -30,6 +30,7 @@
 #include "detection/signature.h"
 #include "detection/rule_option_types.h"
 #include "actions/actions.h"
+#include "time/clock_defs.h"
 
 class IpsOption;
 struct Packet;
@@ -56,15 +57,15 @@ struct OptFpList
 struct OtnState
 {
     // profiling
-#ifdef PERF_PROFILING
-    uint64_t ticks;
-    uint64_t ticks_match;
-    uint64_t ticks_no_match;
+    // FIXIT-L J factor the profiling stuff out
+    hr_duration elapsed;
+    hr_duration elapsed_match;
+    hr_duration elapsed_no_match;
+
     uint64_t checks;
     uint64_t matches;
     uint8_t noalerts;
     uint64_t alerts;
-#endif
 
     // ppm
     uint64_t ppm_suspend_time;
index e49eef7bc5711d08ef3b138a00947828e3240e85..b4459b7e267d132e5c601bff53adcfbee01912e1 100644 (file)
@@ -32,9 +32,7 @@ using namespace std;
 // searches for the detection engine
 static THREAD_LOCAL uint64_t s_bcnt=0;
 
-#ifdef PERF_PROFILING
 THREAD_LOCAL ProfileStats mpsePerfStats;
-#endif
 
 //-------------------------------------------------------------------------
 // base stuff
index 2f5e0da47787b655d7eecbec11025b6d1a359113..fb735f742d6a9d5538a3e152909ce6a557eba916 100644 (file)
@@ -40,6 +40,7 @@
 
 struct SnortConfig;
 struct MpseApi;
+struct ProfileStats;
 
 class SO_PUBLIC Mpse
 {
@@ -85,10 +86,7 @@ private:
     const MpseApi* api;
 };
 
-#ifdef PERF_PROFILING
-struct ProfileStats;
 extern THREAD_LOCAL ProfileStats mpsePerfStats;
-#endif
 
 typedef void (* MpseOptFunc)(SnortConfig*);
 typedef void (* MpseExeFunc)();
index 4bbbd0177d177232c5ef4415a35ccadb89e58d65..b29f2e3a94b338a37a8996181d3b21aafde3441e 100644 (file)
@@ -74,8 +74,7 @@ static void opt_dtor(IpsOption* p)
 class HttpIpsOption : public IpsOption
 {
 public:
-    HttpIpsOption(
-        const char* s, PsIdx psi, CursorActionType c = CAT_SET_OTHER) :
+    HttpIpsOption(const char* s, PsIdx psi, CursorActionType c = CAT_SET_OTHER) :
         IpsOption(s), key(s), cat(c), idx(psi) {}
 
     CursorActionType get_cursor_type() const override
index 3472ad517aeb7bc76da8f0c2ddffbe724c51845f..bdd7ef09cd760409bb60d7898f033b8fd78e6bbd 100644 (file)
@@ -316,7 +316,6 @@ bool SearchEngineModule::set(const char*, Value& v, SnortConfig* sc)
 // profile module
 //-------------------------------------------------------------------------
 
-#ifdef PERF_PROFILING
 static const Parameter profile_rule_params[] =
 {
     { "count", Parameter::PT_INT, "-1:", "-1",
@@ -401,7 +400,6 @@ bool ProfileModule::set(const char* fqn, Value& v, SnortConfig* sc)
 
     return true;
 }
-#endif
 
 //-------------------------------------------------------------------------
 // classification module
@@ -2004,9 +2002,7 @@ void module_init()
     ModuleManager::add_module(new DetectionModule);
     ModuleManager::add_module(new PacketsModule);
     ModuleManager::add_module(new ProcessModule);
-#ifdef PERF_PROFILING
     ModuleManager::add_module(new ProfileModule);
-#endif
     ModuleManager::add_module(new ReferencesModule);
     ModuleManager::add_module(new RuleStateModule);
     ModuleManager::add_module(new SearchEngineModule);
index de5ab70893f1a15a42cfea85f46c1c396214709f..3efc19f63dcca273212e36144b62a17d1901cf54 100644 (file)
@@ -124,7 +124,6 @@ static THREAD_LOCAL Packet* s_packet = nullptr;
 // FIXIT-M move these to appropriate modules
 //-------------------------------------------------------------------------
 
-#ifdef PERF_PROFILING
 static ProfileStats* get_profile(const char* key)
 {
     if ( !strcmp(key, "detect") )
@@ -163,11 +162,8 @@ static ProfileStats* get_profile(const char* key)
     return nullptr;
 }
 
-#endif
-
 static void register_profiles()
 {
-#ifdef PERF_PROFILING
     PerfProfilerManager::register_module("detect", nullptr, get_profile);
     PerfProfilerManager::register_module("mpse", "detect", get_profile);
     PerfProfilerManager::register_module("rebuilt_packet", "detect", get_profile);
@@ -179,7 +175,6 @@ static void register_profiles()
     PerfProfilerManager::register_module("eventq", nullptr, get_profile);
     PerfProfilerManager::register_module("total", nullptr, get_profile);
     PerfProfilerManager::register_module("daq_meta", nullptr, get_profile);
-#endif
 }
 
 //-------------------------------------------------------------------------
@@ -672,9 +667,7 @@ void Snort::thread_term()
 
     DAQ_Delete();
 
-#ifdef PERF_PROFILING
     PerfProfilerManager::consolidate_stats();
-#endif
 
     otnx_match_data_term();
     detection_filter_term();
index 56d7da1fd3aaa4e54cdcd5dff7948def75898ce7..740c1a8a8f57ade930db34f9833622701fb17f33 100644 (file)
@@ -170,10 +170,8 @@ SnortConfig::SnortConfig()
     num_slots = get_instance_max();
     state = (SnortState*)SnortAlloc(sizeof(SnortState)*num_slots);
 
-#ifdef PERF_PROFILING
     profile_rules = (ProfileConfig*)SnortAlloc(sizeof(*profile_rules));
     profile_modules = (ProfileConfig*)SnortAlloc(sizeof(*profile_modules));
-#endif
 
 #ifdef PPM_MGR
     ppm_cfg = (ppm_cfg_t*)SnortAlloc(sizeof(*ppm_cfg));
index 92a9ebe0a6583f4f7dcced31dcff7b168576c740..f362705a428cc5b349ff904b5fe8daa16e7aca33 100644 (file)
@@ -543,13 +543,13 @@ public:
     static long int get_pcre_match_limit_recursion()
     { return snort_conf->pcre_match_limit_recursion; }
 
-#ifdef PERF_PROFILING
+    // FIXIT-H J No longer necessary, since this is always true
+    // or, we make it conditional on definition of table in lua
     static bool get_profile_modules()
     { return snort_conf->profile_modules; }
 
     static bool get_profile_rules()
     { return snort_conf->profile_rules; }
-#endif
 
     static long int get_tagged_packet_limit()
     { return snort_conf->tagged_packet_limit; }
index 6ce4e57edf30fbd96f569e345b8fffada53b8750..2f5daa009673764d0a86139faf2e1f4a120eb1ce 100644 (file)
@@ -44,13 +44,11 @@ struct CodecApi;
 class Codec;
 class Module;
 class PacketManager;
+struct ProfileStats;
 
 //-------------------------------------------------------------------------
 
-#ifdef PERF_PROFILING
-struct ProfileStats;
 extern THREAD_LOCAL ProfileStats decodePerfStats;
-#endif
 
 static const uint16_t max_protocol_id = 65535;
 
index b53ec2cc09d09a05b00c125f7748e123173921d3..ae42f53fcda6de9265552fcef6cd0569c2b207e4 100644 (file)
@@ -784,9 +784,7 @@ void ModuleManager::add_module(Module* m, const BaseApi* b)
     ModHook* mh = new ModHook(m, b);
     s_modules.push_back(mh);
 
-#ifdef PERF_PROFILING
     PerfProfilerManager::register_module(m);
-#endif
 }
 
 Module* ModuleManager::get_module(const char* s)
index 2461506563642ce63d5282a3b60cbb70d0f4e174..1f5e78b1b3bca5b404abff1edf7668cd194a8c4c 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "main/thread.h"
 #include "detection/detection_options.h"
+#include "time/cpuclock.h"
 
 typedef uint64_t PPM_TICKS;
 typedef uint64_t PPM_USECS;
index b53ced4eb8b5d0b071cd6c7c649891a8e6e80ad5..9b3113ddf13a3d3a3d570062951b6e24de6b1f90 100644 (file)
@@ -1,14 +1,10 @@
-set ( PROFILER_SOURCES profiler.cc )
 set ( PROFILER_INCLUDES profiler.h )
+set ( PROFILER_SOURCES profiler.cc )
 
-if ( ENABLE_PERFPROFILING )
-
-    add_library ( profiler STATIC
-        ${PROFILER_SOURCES}
-        ${PROFILER_INCLUDES}
-    )
-
-endif ( ENABLE_PERFPROFILING )
+add_library ( profiler STATIC
+    ${PROFILER_SOURCES}
+    ${PROFILER_INCLUDES}
+)
 
 install (FILES ${PROFILER_INCLUDES}
     DESTINATION "${INCLUDE_INSTALL_PATH}/profiler"
index d41d2f60e0af545bbd9c215bcf8bf990ac5c0c93..e491fc11587da5c06dff8ded01074d5a033eb79f 100644 (file)
@@ -1,13 +1,9 @@
-if PERF_PROFILING
 noinst_LIBRARIES = libprofiler.a
-endif
 
 x_includedir = $(pkgincludedir)/profiler
 
 x_include_HEADERS = profiler.h
 
-if PERF_PROFILING
 libprofiler_a_SOURCES = \
 profiler.cc \
 profiler.h
-endif
index 2dbf79a199ab2036ea6d4aff7d45a9448f95c1b7..5146be5944d52a831fa1adfcdc345c803717fd38 100644 (file)
@@ -102,22 +102,46 @@ public:
     std::set<ModStatsNode*> children;
 
 private:
-    ProfileStats stats { 0, 0 };
+    ProfileStats stats;
     bool totalled = false;
     ModStatsFunctor getter;
 };
 
 struct ModEntry
 {
+    using microseconds = std::chrono::microseconds;
+
     std::string name;
     ModStatsNode* node;
     ProfileStats stats;
-
-    double ticks_per_check;
-    double pct_of_parent;
+    ProfileStats caller_stats;
 
     std::vector<ModEntry> entries;
 
+
+    microseconds us() const
+    {
+        using std::chrono::duration_cast;
+        return duration_cast<microseconds>(stats.elapsed);
+    }
+
+    double avg_check() const
+    { return stats.checks? double(us().count()) / double(stats.checks) : 0.0; }
+
+    double pct_of(const ProfileStats& other) const
+    {
+        using std::chrono::duration_cast;
+
+        auto other_us = duration_cast<microseconds>(other.elapsed).count();
+        if ( other_us )
+            return double(us().count()) / double(other_us) * 100.0;
+
+        return 0.0;
+    }
+
+    double pct_of_caller() const
+    { return pct_of(caller_stats); }
+
     ModEntry(ModStatsNode*, const ProfileStats&);
 };
 
@@ -144,13 +168,41 @@ public:
 
 struct RuleEntry
 {
-    SigInfo sig_info;
+    using microseconds = std::chrono::microseconds;
 
+    SigInfo sig_info;
     OtnState state;
 
-    double ticks_per_check = 0.0;
-    double ticks_per_match = 0.0;
-    double ticks_per_nomatch = 0.0;
+    microseconds us() const
+    {
+        using std::chrono::duration_cast;
+        return duration_cast<microseconds>(state.elapsed);
+    }
+
+    microseconds us_match() const
+    {
+        using std::chrono::duration_cast;
+        return duration_cast<microseconds>(state.elapsed_match);
+    }
+
+    microseconds us_no_match() const
+    {
+        using std::chrono::duration_cast;
+        return duration_cast<microseconds>(state.elapsed_no_match);
+    }
+
+    template<typename T>
+    double us_per(microseconds t, T v) const
+    { return v ? double(t.count()) / double(v) : 0.0; }
+
+    double avg_match() const
+    { return us_per(us_match(), state.matches); }
+
+    double avg_no_match() const
+    { return us_per(us_no_match(), state.checks - state.matches); }
+
+    double avg_check() const
+    { return us_per(us(), state.checks); }
 
     RuleEntry(const SigInfo&, const OtnState&);
 };
@@ -172,9 +224,9 @@ static ModStatsTree s_module_nodes;
 
 static inline OtnState& operator+=(OtnState& lhs, const OtnState& rhs)
 {
-    lhs.ticks += rhs.ticks;
-    lhs.ticks_match += rhs.ticks_match;
-    lhs.ticks_no_match += rhs.ticks_no_match;
+    lhs.elapsed += rhs.elapsed;
+    lhs.elapsed_match += rhs.elapsed_match;
+    lhs.elapsed_no_match += rhs.elapsed_no_match;
     lhs.checks += rhs.checks;
     lhs.matches += rhs.matches;
     lhs.noalerts += rhs.noalerts;
@@ -182,15 +234,6 @@ static inline OtnState& operator+=(OtnState& lhs, const OtnState& rhs)
     return lhs;
 }
 
-static double get_ticks_per_us()
-{
-    static double ticks_per_us = 0.0;
-    if ( ticks_per_us == 0.0 )
-        ticks_per_us = get_ticks_per_usec();
-
-    return ticks_per_us;
-}
-
 template<typename T>
 static void add_module(std::string name, const char* pname, T v)
 {
@@ -235,14 +278,15 @@ static void get_mod_entries(ModEntry& parent, ModEntrySortFunc* sort_fn, int cou
 static void print_mod_entry(int layer, int num, const ModEntry& root, const ModEntry& cur)
 {
     unsigned indent = 6 - (5 - layer) + 2;
+
     LogMessage("%*d%*s%*d" FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n",
         indent, num,
         28 - indent, cur.name.c_str(), 6, layer,
         11, cur.stats.checks,
-        20, uint64_t((double(cur.stats.ticks) / get_ticks_per_us())),
-        11, cur.ticks_per_check / get_ticks_per_us(),
-        10, cur.pct_of_parent,
-        10, double(cur.stats.ticks) / double(root.stats.ticks) * 100.0);
+        20, cur.us().count(),
+        11, cur.avg_check(),
+        10, cur.pct_of_caller(),
+        10, cur.pct_of(root.stats));
 
     int num2 = 0;
     for ( const auto& entry : cur.entries )
@@ -284,15 +328,16 @@ static void print_mod_entries(ModEntry& root, int count)
     for ( const auto& entry : root.entries )
         print_mod_entry(0, ++num, root, entry);
 
-    int indent = root.name.size() + 1;
+    unsigned indent = root.name.size() + 1;
+
     LogMessage("%*s%*s%*d" FMTu64("*") FMTu64("*") "%*.2f%*.2f%*.2f\n",
         indent, root.name.c_str(),
         28 - indent, root.name.c_str(), 6, 0,
         11, root.stats.checks,
-        20, uint64_t(double(root.stats.ticks) / get_ticks_per_us()),
-        11, root.ticks_per_check / get_ticks_per_us(),
-        10, root.pct_of_parent,
-        10, root.pct_of_parent);
+        20, root.us().count(),
+        11, root.avg_check(),
+        10, root.pct_of_caller(),
+        10, root.pct_of_caller());
 }
 
 bool get_mod_sort_function(ProfileSort sort_mode, ModEntrySortFunc& sort_fn)
@@ -306,12 +351,12 @@ bool get_mod_sort_function(ProfileSort sort_mode, ModEntrySortFunc& sort_fn)
 
     case PROFILE_SORT_TOTAL_TICKS:
         sort_fn = [](const ModEntry& a, const ModEntry& b) -> bool
-        { return a.stats.ticks > b.stats.ticks; };
+        { return a.stats.elapsed > b.stats.elapsed; };
         break;
 
     case PROFILE_SORT_AVG_TICKS:
         sort_fn = [](const ModEntry& a, const ModEntry& b) -> bool
-        { return a.ticks_per_check > b.ticks_per_check; };
+        { return a.avg_check() > b.avg_check(); };
         break;
 
     default:
@@ -350,22 +395,22 @@ static void sort_rule_stats(std::vector<RuleEntry>& entries, ProfileSort sort_mo
 
     case PROFILE_SORT_AVG_TICKS_PER_MATCH:
         sort_fn = [](const RuleEntry& a, const RuleEntry& b)
-        { return a.ticks_per_match >= b.ticks_per_match; };
+        { return a.avg_match() >= b.avg_match(); };
         break;
 
     case PROFILE_SORT_AVG_TICKS_PER_NOMATCH:
         sort_fn = [](const RuleEntry& a, const RuleEntry& b)
-        { return a.ticks_per_nomatch >= b.ticks_per_nomatch; };
+        { return a.avg_no_match() >= b.avg_no_match(); };
         break;
 
     case PROFILE_SORT_TOTAL_TICKS:
         sort_fn = [](const RuleEntry& a, const RuleEntry& b)
-        { return a.state.ticks >= b.state.ticks; };
+        { return a.state.elapsed >= b.state.elapsed; };
         break;
 
     case PROFILE_SORT_AVG_TICKS:
         sort_fn = [](const RuleEntry& a, const RuleEntry& b)
-        { return a.ticks_per_check >= b.ticks_per_check; };
+        { return a.avg_check() >= b.avg_check(); };
         break;
 
     default:
@@ -392,7 +437,7 @@ static void get_rule_stats_entries(std::vector<RuleEntry>& entries)
 
         consolidate_otn_states(states);
 
-        if ( !state.checks || !state.ticks )
+        if ( !state.checks || (state.elapsed == hr_duration::zero()) )
             continue;
 
         entries.emplace_back(otn->sigInfo, state);
@@ -471,10 +516,10 @@ static void print_rule_stats(std::vector<RuleEntry>& entries, int num)
             11, entry.state.checks,
             10, entry.state.matches,
             10, entry.state.alerts,
-            20, uint64_t(double(entry.state.ticks) / get_ticks_per_us()),
-            11, entry.ticks_per_check / get_ticks_per_us(),
-            11, entry.ticks_per_match / get_ticks_per_us(),
-            13, entry.ticks_per_nomatch / get_ticks_per_us()
+            20, entry.us().count(),
+            11, entry.avg_check(),
+            11, entry.avg_match(),
+            13, entry.avg_no_match()
 #ifdef PPM_MGR
             , 11, entry.state.ppm_disable_cnt
 #endif
@@ -525,36 +570,12 @@ void ModStatsNode::accumulate()
 }
 
 ModEntry::ModEntry(ModStatsNode* node, const ProfileStats& caller_stats) :
-        name(node->name), node(node), stats(node->get_total())
-{
-    assert(stats.ticks >= stats.checks);
-    assert(caller_stats.ticks >= stats.ticks);
-
-    if ( stats.checks == 0.0 )
-        ticks_per_check = 0.0;
-    else
-        ticks_per_check = double(stats.ticks) / double(stats.checks);
-
-    if ( caller_stats.ticks == 0.0 )
-        pct_of_parent = 0.0;
-    else
-        pct_of_parent = double(stats.ticks) / double(caller_stats.ticks) * 100.0;
-}
+        name(node->name), node(node), stats(node->get_total()), caller_stats(caller_stats)
+{ assert(caller_stats.elapsed >= stats.elapsed); }
 
 RuleEntry::RuleEntry(const SigInfo& si, const OtnState& os) :
     sig_info(si), state(os)
-{
-    ticks_per_check = double(state.ticks) / double(state.checks);
-
-    state.checks = std::max(state.checks, state.matches);
-
-    if ( state.matches )
-        ticks_per_match = double(state.ticks_match) / double(state.matches);
-
-    // can safely replace != with >
-    if ( state.checks != state.matches )
-        ticks_per_nomatch = double(state.ticks_no_match) / double(state.checks - state.matches);
-}
+{ state.checks = std::max(state.checks, state.matches); }
 
 // -----------------------------------------------------------------------------
 // public API
@@ -682,6 +703,9 @@ void PerfProfilerManager::reset_all_stats()
 
 #ifdef UNIT_TEST
 
+constexpr hr_duration operator "" _dur(unsigned long long v)
+{ return hr_duration(v); }
+
 struct ProfilePauseObserver
 {
     void start()
@@ -701,18 +725,18 @@ struct ProfilePauseObserver
 
 TEST_CASE( "profile stats", "[profiler]" )
 {
-    ProfileStats stats = { 1, 2 };
+    ProfileStats stats = { 1_ticks , 2 };
 
     SECTION( "operator bool()" )
     {
         CHECK( stats );
-        stats = { 0, 0 };
+        stats = { 0_dur, 0 };
         CHECK_FALSE( stats );
     }
 
     SECTION( "operator==" )
     {
-        ProfileStats compare = { 0, 0 };
+        ProfileStats compare = { 0_ticks, 0 };
         CHECK_FALSE( stats == compare );
         compare = stats;
         CHECK( stats == compare );
@@ -726,8 +750,8 @@ TEST_CASE( "profile stats", "[profiler]" )
 
     SECTION( "operator+=" )
     {
-        ProfileStats inc = { 3, 4 };
-        ProfileStats expected = { stats.ticks + inc.ticks, stats.checks + inc.checks };
+        ProfileStats inc = { 3_ticks, 4 };
+        ProfileStats expected = { stats.elapsed + inc.elapsed, stats.checks + inc.checks };
         stats += inc;
 
         CHECK( stats == expected );
@@ -739,7 +763,7 @@ TEST_CASE( "stopwatch", "[profiler]" )
     Stopwatch sw;
 
     REQUIRE_FALSE( sw.alive() );
-    REQUIRE( sw.get() == 0 );
+    REQUIRE( sw.get() == 0_ticks );
 
     SECTION( "start" )
     {
@@ -752,7 +776,7 @@ TEST_CASE( "stopwatch", "[profiler]" )
 
         SECTION( "running elapsed time should be non-zero" )
         {
-            CHECK( sw.get() > 0 );
+            CHECK( sw.get() > 0_ticks );
         }
 
         SECTION( "start on running clock has no effect" )
@@ -797,7 +821,7 @@ TEST_CASE( "stopwatch", "[profiler]" )
         {
             sw.reset();
             CHECK_FALSE( sw.alive() );
-            CHECK( sw.get() == 0 );
+            CHECK( sw.get() == 0_ticks );
         }
 
         SECTION( "reset on stopped clock" )
@@ -805,7 +829,7 @@ TEST_CASE( "stopwatch", "[profiler]" )
             sw.stop();
             sw.reset();
             CHECK_FALSE( sw.alive() );
-            CHECK( sw.get() == 0 );
+            CHECK( sw.get() == 0_ticks );
         }
     }
 
@@ -816,7 +840,7 @@ TEST_CASE( "stopwatch", "[profiler]" )
         {
             sw.cancel();
             CHECK_FALSE( sw.alive() );
-            CHECK( sw.get() == 0 );
+            CHECK( sw.get() == 0_ticks );
         }
 
         SECTION( "cancel on stopped clock that has lap time" )
@@ -836,7 +860,7 @@ TEST_CASE( "perf profiler base", "[profiler]" )
     SECTION( "profiler is started on instantiation" )
     {
         PerfProfilerBase prof;
-        CHECK( prof.get_delta() > 0 );
+        CHECK( prof.get_delta() > 0_ticks );
     }
 
     SECTION( "profiler evaluates to true" )
@@ -848,9 +872,9 @@ TEST_CASE( "perf profiler base", "[profiler]" )
 
 TEST_CASE( "perf profiler", "[profiler]" )
 {
-    ProfileStats stats = { 0, 0 };
+    ProfileStats stats = { 0_ticks, 0 };
 
-    REQUIRE( stats.ticks == 0 );
+    REQUIRE( stats.elapsed == 0_ticks );
     REQUIRE( stats.checks == 0 );
 
     SECTION( "going out of scope causes profiler to update stats" )
@@ -859,7 +883,7 @@ TEST_CASE( "perf profiler", "[profiler]" )
             PerfProfiler prof(stats);
         }
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
     }
 
@@ -870,7 +894,7 @@ TEST_CASE( "perf profiler", "[profiler]" )
         ProfileStats saved = stats;
         prof.stop();
 
-        CHECK( saved.ticks == stats.ticks );
+        CHECK( saved.elapsed == stats.elapsed );
         CHECK( saved.checks == stats.checks );
     }
 
@@ -880,7 +904,7 @@ TEST_CASE( "perf profiler", "[profiler]" )
         prof.pause();
         prof.stop();
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
     }
 
@@ -890,12 +914,12 @@ TEST_CASE( "perf profiler", "[profiler]" )
         prof.pause();
         prof.start();
 
-        CHECK( stats.ticks == 0 );
+        CHECK( stats.elapsed == 0_ticks );
         CHECK( stats.checks == 0 );
 
         prof.stop();
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
     }
 
@@ -910,7 +934,7 @@ TEST_CASE( "perf profiler", "[profiler]" )
         catch( int& )
         { }
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
     }
 }
@@ -926,12 +950,12 @@ TEST_CASE( "node perf profiler", "[profiler]" )
             NodePerfProfiler prof(stats);
         }
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
 
         SECTION( "evaluates to NO MATCH by default" )
         {
-            CHECK( stats.ticks_no_match > 0 );
+            CHECK( stats.elapsed_no_match > 0_ticks );
         }
     }
 
@@ -942,13 +966,13 @@ TEST_CASE( "node perf profiler", "[profiler]" )
         dot_node_state_t saved = stats;
         prof.stop(true);
 
-        CHECK( saved.ticks == stats.ticks );
+        CHECK( saved.elapsed == stats.elapsed );
         CHECK( saved.checks == stats.checks );
 
         SECTION( "only one of match or no match is updated" )
         {
-            CHECK( stats.ticks_no_match > 0 );
-            CHECK( stats.ticks_match == 0 );
+            CHECK( stats.elapsed_no_match > 0_ticks );
+            CHECK( stats.elapsed_match == 0_ticks );
         }
     }
 
@@ -958,7 +982,7 @@ TEST_CASE( "node perf profiler", "[profiler]" )
         prof.pause();
         prof.stop(false);
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
     }
 
@@ -968,12 +992,12 @@ TEST_CASE( "node perf profiler", "[profiler]" )
         prof.pause();
         prof.start();
 
-        CHECK( stats.ticks == 0 );
+        CHECK( stats.elapsed == 0_ticks );
         CHECK( stats.checks == 0 );
 
         prof.stop(false);
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
     }
 
@@ -982,11 +1006,11 @@ TEST_CASE( "node perf profiler", "[profiler]" )
         NodePerfProfiler prof(stats);
         prof.stop(true);
 
-        CHECK( stats.ticks_match > 0 );
+        CHECK( stats.elapsed_match > 0_ticks );
 
         SECTION( "and doesn't update NO MATCH" )
         {
-            CHECK( stats.ticks_no_match == 0 );
+            CHECK( stats.elapsed_no_match == 0_ticks );
         }
     }
 
@@ -1001,7 +1025,7 @@ TEST_CASE( "node perf profiler", "[profiler]" )
         catch( int& )
         { }
 
-        CHECK( stats.ticks > 0 );
+        CHECK( stats.elapsed > 0_ticks );
         CHECK( stats.checks == 1 );
     }
 }
@@ -1146,7 +1170,7 @@ TEST_CASE( "mod stats node", "[profiler]" )
 
     SECTION( "copy-constructed node retains stats" )
     {
-        mod_stats_test_stats = { 1, 2 };
+        mod_stats_test_stats = { 1_ticks, 2 };
         node.set(mock_get_profile_func);
         node.accumulate();
         auto orig_stats = node.get_total();
@@ -1159,7 +1183,7 @@ TEST_CASE( "mod stats node", "[profiler]" )
 
     SECTION( "accumulate() and get_total() correctly adds stats" )
     {
-        mod_stats_test_stats = { 1, 2 };
+        mod_stats_test_stats = { 1_ticks, 2 };
         ProfileStats expected = mod_stats_test_stats;
         expected += mod_stats_test_stats;
 
@@ -1191,8 +1215,8 @@ TEST_CASE( "mod stats tree", "[profiler]" )
 
 TEST_CASE( "mod entry", "[profiler]" )
 {
-    ProfileStats stats = { 2, 1 };
-    ProfileStats caller_stats = { 20, 10 };
+    ProfileStats stats = { 200_ticks, 1 };
+    ProfileStats caller_stats = { 2000_ticks, 10 };
     MockProfilerModule m(&stats);
     ModStatsNode node("a");
 
@@ -1205,21 +1229,29 @@ TEST_CASE( "mod entry", "[profiler]" )
 
     SECTION( "ctor calculates percentages" )
     {
-        CHECK( entry.ticks_per_check == 2.0 );
-        CHECK( entry.pct_of_parent == 2.0 / 20.0 * 100.0 );
+        using std::chrono::duration_cast;
+        using std::chrono::microseconds;
+
+        const auto exp_avg_check = double(duration_cast<microseconds>(200_ticks).count());
+        const auto exp_pct = double(duration_cast<microseconds>(200_ticks).count()) /
+            double(duration_cast<microseconds>(2000_ticks).count()) * 100.0;
+
+
+        CHECK( entry.avg_check() == exp_avg_check );
+        CHECK( entry.pct_of_caller() == exp_pct );
     }
 
     SECTION( "zeros" )
     {
-        stats = { 0, 0 };
-        caller_stats = { 0, 0 };
+        stats = { 0_ticks, 0 };
+        caller_stats = { 0_ticks, 0 };
         node.reset();
         node.accumulate();
 
         ModEntry entry(&node, caller_stats);
 
-        CHECK( entry.ticks_per_check == 0.0 );
-        CHECK( entry.pct_of_parent == 0.0 );
+        CHECK( entry.avg_check() == 0.0 );
+        CHECK( entry.pct_of_caller() == 0.0 );
     }
 }
 
index 63ae33049823547e7fa3e15d45c3e7c4195e9982..45cf0dbba9a997d93b929f61dcc984c931afe36e 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "main/snort_types.h"
 #include "main/thread.h"
-#include "time/cpuclock.h"
+#include "time/stopwatch.h"
 
 class Module;
 
@@ -48,105 +48,31 @@ enum ProfileSort
 
 struct ProfileStats
 {
-    uint64_t ticks;
-    uint64_t checks;
+    hr_duration elapsed = 0_ticks;
+    uint64_t checks = 0;
 
-    void update(uint64_t elapsed)
-    { ++checks; ticks += elapsed; }
+    void update(hr_duration delta)
+    { ++checks; elapsed += delta; }
 
     void reset()
-    { ticks = 0; checks = 0; }
+    { elapsed = 0_ticks; checks = 0; }
 
     bool operator==(const ProfileStats& rhs)
-    { return ticks == rhs.ticks && checks == rhs.checks; }
+    { return elapsed == rhs.elapsed && checks == rhs.checks; }
 
     operator bool() const
-    { return ticks || checks; }
+    { return (elapsed > hr_duration::zero()) || checks; }
 
     ProfileStats& operator+=(const ProfileStats& rhs)
     {
-        ticks += rhs.ticks;
+        elapsed += rhs.elapsed;
         checks += rhs.checks;
         return *this;
     }
-};
-
-struct RuleProfileStats : ProfileStats
-{
-    uint64_t ticks_match;
-
-    void update(uint64_t elapsed, bool match)
-    {
-        ProfileStats::update(elapsed);
-        if ( match )
-            ticks_match += elapsed;
-    }
-
-    void reset()
-    { ProfileStats::reset(); ticks_match = 0; }
-
-    RuleProfileStats& operator+=(const RuleProfileStats& o)
-    {
-        ticks += o.ticks;
-        checks += o.checks;
-        ticks_match += o.ticks_match;
-        return *this;
-    }
-};
-
-// FIXIT-L should go in its own module
-class Stopwatch
-{
-public:
-    Stopwatch() :
-        elapsed { 0 }, running { false } { }
-
-    void start()
-    {
-        if ( running )
-            return;
-
-        get_clockticks(ticks_start);
-        running = true;
-    }
 
-    void stop()
-    {
-        if ( !running )
-            return;
-
-        elapsed += get_delta();
-        running = false;
-    }
-
-    uint64_t get() const
-    {
-        if ( running )
-            return elapsed + get_delta();
-
-        return elapsed;
-    }
-
-    bool alive() const
-    { return running; }
-
-    void reset()
-    { running = false; elapsed = 0; }
-
-    void cancel()
-    { running = false; }
-
-private:
-    uint64_t get_delta() const
-    {
-        uint64_t ticks_stop;
-        get_clockticks(ticks_stop);
-        return ticks_stop - ticks_start;
-    }
-
-    uint64_t elapsed;
-    bool running;
-    uint64_t ticks_start;
+    ProfileStats() = default;
+    ProfileStats(hr_duration elapsed, uint64_t checks) :
+        elapsed(elapsed), checks(checks) { }
 };
 
 class PerfProfilerBase
@@ -165,7 +91,7 @@ public:
     operator bool() const
     { return true; }
 
-    uint64_t get_delta() const
+    hr_duration get_delta() const
     { return sw.get(); }
 
 private:
@@ -244,15 +170,6 @@ struct ProfilerPause
 // thread local access method
 using get_profile_func = ProfileStats* (*)(const char*);
 
-#ifdef PERF_PROFILING
-#ifndef PROFILING_MODULES
-#define PROFILING_MODULES SnortConfig::get_profile_modules()
-#endif
-
-#ifndef PROFILING_RULES
-#define PROFILING_RULES SnortConfig::get_profile_rules()
-#endif
-
 #define PERF_PROFILER_NAME(stats) \
     stats ## _perf_profiler
 
@@ -320,20 +237,5 @@ struct ProfileConfig
 extern THREAD_LOCAL ProfileStats totalPerfStats;
 extern THREAD_LOCAL ProfileStats metaPerfStats;
 
-#else
-#define PERF_PROFILER_NAME(stats)
-#define PERF_PAUSE_NAME(stats)
-#define PERF_PROFILE(stats)
-#define PERF_PROFILE_THREAD_LOCAL(stats, idx)
-#define PERF_PROFILE_BLOCK(stats)
-#define PERF_PROFILE_THREAD_LOCAL_BLOCK(stats, idx)
-#define NODE_PERF_PROFILE(stats)
-#define NODE_PERF_PROFILE_BLOCK(stats)
-#define NODE_PERF_PROFILE_STOP(stats, match)
-#define NODE_PERF_PROFILE_STOP_MATCH(stats)
-#define NODE_PERF_PROFILE_STOP_NO_MATCH(stats)
-#define PERF_PAUSE_BLOCK(stats)
-
-#endif // PERF_PROFILING
 #endif
 
index 00cea6f04794758ff41966763ceb6f5203ee024e..d6e004944420c7189dec6fcff443e2fb1feaf90f 100644 (file)
@@ -50,9 +50,7 @@
 #include "packet_io/sfdaq.h"
 #include "packet_io/active.h"
 
-#ifdef PERF_PROFILING
 THREAD_LOCAL ProfileStats decodePerfStats;
-#endif
 
 // Decoding statistics
 
index bf3a5136b2af23382e8c5d73bdd3c30b4d141425..d87642d0f46a6c8e9ee65d12a9a67b822b2846b9 100644 (file)
@@ -68,7 +68,6 @@
 #include "framework/data_bus.h"
 #include "sfip/sf_ip.h"
 
-#ifdef PERF_PROFILING
 // FIXIT-M ftp, http, etc. should not be calling snort_detect()
 static THREAD_LOCAL int ftppDetectCalled = 0;
 static THREAD_LOCAL ProfileStats ftppDetectPerfStats;
@@ -77,15 +76,13 @@ void ft_update_perf(ProfileStats& stats)
 {
     if (ftppDetectCalled)
     {
-        stats.ticks -= ftppDetectPerfStats.ticks;
-        /* And Reset ticks to 0 */
-        ftppDetectPerfStats.ticks = 0;
+        stats.elapsed -= ftppDetectPerfStats.elapsed;
+        ftppDetectPerfStats.reset();
+        // FIXIT-L J should be a bool
         ftppDetectCalled = 0;
     }
 }
 
-#endif
-
 void CleanupFTPCMDConf(void* ftpCmd)
 {
     FTP_CMD_CONF* FTPCmd = (FTP_CMD_CONF*)ftpCmd;
@@ -262,8 +259,6 @@ void do_detection(Packet* p)
     get_data_bus().publish(PACKET_EVENT, p);
 
     DisableInspection(p);
-#ifdef PERF_PROFILING
     ftppDetectCalled = 1;
-#endif
 }
 
index 0f82c9b18beb5fa646755dff13a143e15e0212a3..aadf0d6e30760cd5717ac3d78b829c674c8a5044 100644 (file)
@@ -42,6 +42,8 @@
 
 #define BUF_SIZE 1024
 
+struct ProfileStats;
+
 extern int16_t ftp_data_app_id;
 
 void do_detection(Packet*);
@@ -57,10 +59,7 @@ int FTPCheckConfigs(SnortConfig*, void*);
 FTP_CLIENT_PROTO_CONF* get_ftp_client(Packet*);
 FTP_SERVER_PROTO_CONF* get_ftp_server(Packet*);
 
-#ifdef PERF_PROFILING
-struct ProfileStats;
 void ft_update_perf(ProfileStats&);
-#endif
 
 #endif
 
index b3896fde7e5f064a5e48565569588e1e8f832402..a5cec68430e76e5ab77ee033d1bf10e932702e88 100644 (file)
@@ -130,9 +130,7 @@ static int SnortFTP(
         do_detection(p);
     }
 
-#ifdef PERF_PROFILING
     ft_update_perf(ftpPerfStats);
-#endif
 
     return ret;
 }
index a4dc5e00ce78f8bcfbd731ef06d87f19a7afe2e8..1cf7c0c35681c58d6198e645db93d3f6838c2c68 100644 (file)
@@ -97,9 +97,7 @@ static int SnortTelnet(TELNET_PROTO_CONF* telnet_config, TELNET_SESSION* Telnets
     else
         do_detection(p);
 
-#ifdef PERF_PROFILING
     ft_update_perf(telnetPerfStats);
-#endif
 
     return FTPP_SUCCESS;
 }
index cb9e3ae78bcee53be9971a01f518c3b7953cb962..61fdd72b7ac1d9510b6b8c27f32f7c623ae28048 100644 (file)
@@ -613,9 +613,8 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p)
         PERF_PROFILE_BLOCK(hiDetectPerfStats)
         {
             get_data_bus().publish(PACKET_EVENT, p);
-#ifdef PERF_PROFILING
+            // FIXIT-L J should be a bool
             hiDetectCalled = 1;
-#endif
         }
 
         return 0;
@@ -1108,9 +1107,7 @@ int HttpInspectMain(HTTPINSPECT_CONF* conf, Packet* p)
         PERF_PROFILE_BLOCK(hiDetectPerfStats)
         {
             snort_detect(p);
-#ifdef PERF_PROFILING
             hiDetectCalled = 1;
-#endif
         }
 
         /*
index 3e6ee4345026347bb1e5adb570c651cb4e8b0b5b..089635b9eff46099a96b63490a3cd102535aa9c2 100644 (file)
@@ -49,6 +49,8 @@
 #define DEFLATE_WBITS      15
 #define GZIP_WBITS         31
 
+struct ProfileStats;
+
 enum HTTP_BUFFER
 {
     HTTP_BUFFER_NONE,
@@ -76,11 +78,8 @@ extern SO_PUBLIC THREAD_LOCAL uint32_t http_mask;
 extern SO_PUBLIC THREAD_LOCAL HttpBuffer http_buffer[HTTP_BUFFER_MAX];
 extern THREAD_LOCAL DataBuffer HttpDecodeBuf;
 
-#ifdef PERF_PROFILING
-struct ProfileStats;
 extern THREAD_LOCAL ProfileStats hiDetectPerfStats;
 extern THREAD_LOCAL int hiDetectCalled;
-#endif
 
 typedef enum _HttpRespCompressType
 {
index a97fa8bae71d044d1cab7047f474e972e8d23c4f..1379acbe3080608937ff6ac7560f249a9725d443 100644 (file)
@@ -338,15 +338,12 @@ void HttpInspect::eval(Packet* p)
      * spent in snort_detect().
      * Subtract the ticks from this if iCallDetect == 0
      */
-#ifdef PERF_PROFILING
     if (hiDetectCalled)
     {
-        hiPerfStats.ticks -= hiDetectPerfStats.ticks;
-        /* And Reset ticks to 0 */
-        hiDetectPerfStats.ticks = 0;
+        hiPerfStats.elapsed -= hiDetectPerfStats.elapsed;
+        hiDetectPerfStats.reset();
         hiDetectCalled = 0;
     }
-#endif
 }
 
 //-------------------------------------------------------------------------
index ee7b71cfabdda3342d67c79d783c249c485e2737..bb4d7856c0c4c1476cfb3429c461fe5600aeac96 100644 (file)
@@ -8,6 +8,8 @@ set ( TIME_INTERNAL_SOURCES
 
 set ( TIME_INCLUDES
     cpuclock.h
+    clock_defs.h
+    stopwatch.h
     )
 
 add_library ( time STATIC
index 84f17f391d0104299d2fd857025e75202fa9de73..ee5ee0cdaad6bfb7d06299500a0a378415b023a9 100644 (file)
@@ -3,11 +3,15 @@ noinst_LIBRARIES = libtime.a
 x_includedir = $(pkgincludedir)/time
 
 x_include_HEADERS = \
-cpuclock.h
+cpuclock.h \
+clock_defs.h \
+stopwatch.h
 
 libtime_a_SOURCES = \
 packet_time.cc \
 packet_time.h \
 periodic.cc \
 periodic.h \
-timersub.h
+timersub.h \
+clock_defs.h \
+stopwatch.h
diff --git a/src/time/clock_defs.h b/src/time/clock_defs.h
new file mode 100644 (file)
index 0000000..abbb1e4
--- /dev/null
@@ -0,0 +1,32 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// clock_defs.h author Joel Cornett <jocornet@cisco.com>
+
+#ifndef CLOCK_DEFS_H
+#define CLOCK_DEFS_H
+
+#include <chrono>
+
+using hr_clock = std::chrono::high_resolution_clock;
+using hr_duration = hr_clock::duration;
+using hr_time = hr_clock::time_point;
+
+inline constexpr hr_duration operator "" _ticks (unsigned long long int v)
+{ return hr_duration(v); }
+
+#endif
index 74870ed32d62653088e611ca46ea2017cf0bb637..50fc3b2409527bfd2717ed226381b264f16ac891 100644 (file)
@@ -5,3 +5,5 @@ This module provides miscellaneous utilities related to timing.
 
 * Packet time manages the updating and reading of a clock based on time values
   from acquired packets.
+
+* Stopwatch is a timekeeping utility that can be started and paused
diff --git a/src/time/stopwatch.h b/src/time/stopwatch.h
new file mode 100644 (file)
index 0000000..f6d6339
--- /dev/null
@@ -0,0 +1,77 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2015-2015 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program 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
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// stopwatch.h author Joel Cornett <jocornet@cisco.com>
+
+#ifndef STOPWATCH_H
+#define STOPWATCH_H
+
+#include <chrono>
+
+#include "clock_defs.h"
+
+class Stopwatch
+{
+public:
+    Stopwatch() :
+        elapsed { hr_duration::zero() }, running { false } { }
+
+    void start()
+    {
+        if ( running )
+            return;
+
+        start_time = hr_clock::now();
+        running = true;
+    }
+
+    void stop()
+    {
+        if ( !running )
+            return;
+
+        elapsed += get_delta();
+        running = false;
+    }
+
+    hr_duration get() const
+    {
+        if ( running )
+            return elapsed + get_delta();
+
+        return elapsed;
+    }
+
+    bool alive() const
+    { return running; }
+
+    void reset()
+    { running = false; elapsed = hr_duration::zero(); }
+
+    void cancel()
+    { running = false; }
+
+private:
+    hr_duration get_delta() const
+    { return hr_clock::now() - start_time; }
+
+    hr_duration elapsed;
+    bool running;
+    hr_time start_time;
+};
+
+#endif
index cbc82a31f7aa3ce613f2533bc107a65b2b31d81c..cfb17477a8d5fab0e0f644d0a6319a2631dcc841 100644 (file)
@@ -350,8 +350,8 @@ void PrintStatistics(void)
     fpShowEventStats(snort_conf);
     print_thresholding(snort_conf->threshold_config, 1);
 
-#ifdef PERF_PROFILING
     {
+        // FIXIT-L J can do flag saving with RAII (much cleaner)
         int save_quiet_flag = snort_conf->logging_flags & LOGGING_FLAG__QUIET;
 
         snort_conf->logging_flags &= ~LOGGING_FLAG__QUIET;
@@ -360,7 +360,6 @@ void PrintStatistics(void)
 
         snort_conf->logging_flags |= save_quiet_flag;
     }
-#endif
 }
 
 //-------------------------------------------------------------------------