224 lines
7.0 KiB
C
Executable File
224 lines
7.0 KiB
C
Executable File
/*
|
|
** Copyright (C) 2014-2016 Cisco and/or its affiliates. All rights reserved.
|
|
** Copyright (C) 2005-2013 Sourcefire, Inc.
|
|
** Author: Steven Sturges <ssturges@sourcefire.com>
|
|
**
|
|
** 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.
|
|
*/
|
|
|
|
/* $Id$ */
|
|
|
|
#ifndef __PROFILER_H__
|
|
#define __PROFILER_H__
|
|
|
|
#ifdef PERF_PROFILING
|
|
|
|
#include "cpuclock.h"
|
|
|
|
/* Sort preferences for rule profiling */
|
|
#define PROFILE_SORT_CHECKS 1
|
|
#define PROFILE_SORT_MATCHES 2
|
|
#define PROFILE_SORT_NOMATCHES 3
|
|
#define PROFILE_SORT_AVG_TICKS 4
|
|
#define PROFILE_SORT_AVG_TICKS_PER_MATCH 5
|
|
#define PROFILE_SORT_AVG_TICKS_PER_NOMATCH 6
|
|
#define PROFILE_SORT_TOTAL_TICKS 7
|
|
|
|
/* MACROS that handle profiling of rules and preprocessors */
|
|
#define PROFILE_VARS_NAMED(name) uint64_t name##_ticks_start, name##_ticks_end
|
|
#define PROFILE_VARS PROFILE_VARS_NAMED(snort)
|
|
|
|
#define PROFILE_START_NAMED(name) \
|
|
get_clockticks(name##_ticks_start)
|
|
|
|
#define PROFILE_END_NAMED(name) \
|
|
get_clockticks(name##_ticks_end)
|
|
|
|
#define NODE_PROFILE_END \
|
|
PROFILE_END_NAMED(node); \
|
|
node_ticks_delta = node_ticks_end - node_ticks_start
|
|
|
|
#ifndef PROFILING_RULES
|
|
#define PROFILING_RULES ScProfileRules()
|
|
#endif
|
|
|
|
#define NODE_PROFILE_VARS uint64_t node_ticks_start, node_ticks_end, node_ticks_delta, node_deltas = 0
|
|
|
|
#define NODE_PROFILE_START(node) \
|
|
if (PROFILING_RULES) { \
|
|
node->checks++; \
|
|
PROFILE_START_NAMED(node); \
|
|
}
|
|
|
|
#define NODE_PROFILE_END_MATCH(node) \
|
|
if (PROFILING_RULES) { \
|
|
NODE_PROFILE_END; \
|
|
node->ticks += node_ticks_delta + node_deltas; \
|
|
node->ticks_match += node_ticks_delta + node_deltas; \
|
|
}
|
|
|
|
#define NODE_PROFILE_END_NOMATCH(node) \
|
|
if (PROFILING_RULES) { \
|
|
NODE_PROFILE_END; \
|
|
node->ticks += node_ticks_delta + node_deltas; \
|
|
node->ticks_no_match += node_ticks_delta + node_deltas; \
|
|
}
|
|
|
|
#define NODE_PROFILE_TMPSTART(node) \
|
|
if (PROFILING_RULES) { \
|
|
PROFILE_START_NAMED(node); \
|
|
}
|
|
|
|
#define NODE_PROFILE_TMPEND(node) \
|
|
if (PROFILING_RULES) { \
|
|
NODE_PROFILE_END; \
|
|
node_deltas += node_ticks_delta; \
|
|
}
|
|
|
|
#define OTN_PROFILE_ALERT(otn) otn->alerts++;
|
|
|
|
#ifndef PROFILING_PREPROCS
|
|
#define PROFILING_PREPROCS ScProfilePreprocs()
|
|
#endif
|
|
|
|
#define PREPROC_PROFILE_START_NAMED(name, ppstat) \
|
|
if (PROFILING_PREPROCS) { \
|
|
ppstat.checks++; \
|
|
PROFILE_START_NAMED(name); \
|
|
ppstat.ticks_start = name##_ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_START(ppstat) PREPROC_PROFILE_START_NAMED(snort, ppstat)
|
|
|
|
#define PREPROC_PROFILE_START_NAMED_PI(name, ppstat) \
|
|
{ \
|
|
ppstat.checks++; \
|
|
PROFILE_START_NAMED(name); \
|
|
ppstat.ticks_start = name##_ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_START_PI(ppstat) PREPROC_PROFILE_START_NAMED_PI(snort, ppstat)
|
|
|
|
#define PREPROC_PROFILE_REENTER_START_NAMED(name, ppstat) \
|
|
if (PROFILING_PREPROCS) { \
|
|
PROFILE_START_NAMED(name); \
|
|
ppstat.ticks_start = name##_ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_REENTER_START(ppstat) PREPROC_PROFILE_REENTER_START_NAMED(snort, ppstat)
|
|
|
|
#define PREPROC_PROFILE_TMPSTART_NAMED(name, ppstat) \
|
|
if (PROFILING_PREPROCS) { \
|
|
PROFILE_START_NAMED(name); \
|
|
ppstat.ticks_start = name##_ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_TMPSTART(ppstat) PREPROC_PROFILE_TMPSTART_NAMED(snort, ppstat)
|
|
|
|
#define PREPROC_PROFILE_END_NAMED(name, ppstat) \
|
|
if (PROFILING_PREPROCS) { \
|
|
PROFILE_END_NAMED(name); \
|
|
ppstat.exits++; \
|
|
ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_END(ppstat) PREPROC_PROFILE_END_NAMED(snort, ppstat)
|
|
|
|
#define PREPROC_PROFILE_END_NAMED_PI(name, ppstat) \
|
|
{ \
|
|
PROFILE_END_NAMED(name); \
|
|
ppstat.exits++; \
|
|
ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_END_PI(ppstat) PREPROC_PROFILE_END_NAMED_PI(snort, ppstat)
|
|
|
|
#define PREPROC_PROFILE_REENTER_END_NAMED(name, ppstat) \
|
|
if (PROFILING_PREPROCS) { \
|
|
PROFILE_END_NAMED(name); \
|
|
ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_REENTER_END(ppstat) PREPROC_PROFILE_REENTER_END_NAMED(snort, ppstat)
|
|
|
|
#define PREPROC_PROFILE_TMPEND_NAMED(name, ppstat) \
|
|
if (PROFILING_PREPROCS) { \
|
|
PROFILE_END_NAMED(name); \
|
|
ppstat.ticks += name##_ticks_end - ppstat.ticks_start; \
|
|
}
|
|
#define PREPROC_PROFILE_TMPEND(ppstat) PREPROC_PROFILE_TMPEND_NAMED(snort, ppstat)
|
|
|
|
/************** Profiling API ******************/
|
|
void ShowRuleProfiles(void);
|
|
|
|
/* Preprocessor stats info */
|
|
typedef struct _PreprocStats
|
|
{
|
|
uint64_t ticks, ticks_start;
|
|
uint64_t checks;
|
|
uint64_t exits;
|
|
} PreprocStats;
|
|
|
|
typedef void (*FreeFunc)(PreprocStats *stats);
|
|
|
|
typedef struct _PreprocStatsNode
|
|
{
|
|
PreprocStats *stats;
|
|
char *name;
|
|
int layer;
|
|
FreeFunc freefn;
|
|
PreprocStats *parent;
|
|
|
|
struct _PreprocStatsNode *next;
|
|
} PreprocStatsNode;
|
|
|
|
typedef struct _ProfileConfig
|
|
{
|
|
int num;
|
|
int sort;
|
|
int append;
|
|
char *filename;
|
|
|
|
} ProfileConfig;
|
|
|
|
typedef void (*StatsNodeFreeFunc)(PreprocStats *stats);
|
|
void RegisterPreprocessorProfile(const char *keyword, PreprocStats *stats, int layer, PreprocStats *parent, StatsNodeFreeFunc freefn);
|
|
void ShowPreprocProfiles(void);
|
|
void ResetRuleProfiling(void);
|
|
void ResetPreprocProfiling(void);
|
|
void CleanupPreprocStatsNodeList(void);
|
|
extern PreprocStats totalPerfStats;
|
|
#else
|
|
#define PROFILE_VARS
|
|
#define PROFILE_VARS_NAMED(name)
|
|
#define NODE_PROFILE_VARS
|
|
#define NODE_PROFILE_START(node)
|
|
#define NODE_PROFILE_END_MATCH(node)
|
|
#define NODE_PROFILE_END_NOMATCH(node)
|
|
#define NODE_PROFILE_TMPSTART(node)
|
|
#define NODE_PROFILE_TMPEND(node)
|
|
#define OTN_PROFILE_ALERT(otn)
|
|
#define PREPROC_PROFILE_START(ppstat)
|
|
#define PREPROC_PROFILE_START_NAMED(name, ppstat)
|
|
#define PREPROC_PROFILE_START_PI(ppstat)
|
|
#define PREPROC_PROFILE_REENTER_START(ppstat)
|
|
#define PREPROC_PROFILE_REENTER_START_NAMED(name, ppstat)
|
|
#define PREPROC_PROFILE_TMPSTART(ppstat)
|
|
#define PREPROC_PROFILE_TMPSTART_NAMED(name, ppstat)
|
|
#define PREPROC_PROFILE_END(ppstat)
|
|
#define PREPROC_PROFILE_END_NAMED(name, ppstat)
|
|
#define PREPROC_PROFILE_END_PI(ppstat)
|
|
#define PREPROC_PROFILE_REENTER_END(ppstat)
|
|
#define PREPROC_PROFILE_REENTER_END_NAMED(name, ppstat)
|
|
#define PREPROC_PROFILE_TMPEND(ppstat)
|
|
#define PREPROC_PROFILE_TMPEND_NAMED(name, ppstat)
|
|
#endif
|
|
|
|
#endif /* __PROFILER_H__ */
|