From ceb7e495ae68bf8f8ef640a015ec66318f604d18 Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Sun, 4 Oct 2009 18:54:51 +0530 Subject: [PATCH] refactoring perf stats code --- src/app-layer-detect-proto.c | 2 +- src/counters.c | 1931 +++++++++++++++++++--------------- src/counters.h | 250 +++-- src/decode-ethernet.c | 2 +- src/decode-gre.c | 2 +- src/decode-icmpv4.c | 2 +- src/decode-icmpv6.c | 2 +- src/decode-ipv4.c | 2 +- src/decode-ipv6.c | 2 +- src/decode-ppp.c | 2 +- src/decode-pppoe.c | 4 +- src/decode-sll.c | 2 +- src/decode-tcp.c | 2 +- src/decode-udp.c | 2 +- src/detect-engine.c | 7 +- src/eidps.c | 8 +- src/flow.c | 2 +- src/source-nfq.c | 63 +- src/source-pcap-file.c | 62 +- src/source-pcap.c | 62 +- src/source-pfring.c | 62 +- src/stream-tcp.c | 13 +- src/threadvars.h | 5 +- src/tm-threads.c | 10 +- src/tmqh-flow.c | 4 +- src/tmqh-simple.c | 4 +- src/util-error.h | 6 + 27 files changed, 1404 insertions(+), 1111 deletions(-) diff --git a/src/app-layer-detect-proto.c b/src/app-layer-detect-proto.c index 0987bf2293..c4d3c0d308 100644 --- a/src/app-layer-detect-proto.c +++ b/src/app-layer-detect-proto.c @@ -380,7 +380,7 @@ void *AppLayerDetectProtoThread(void *td) } if (TmThreadsCheckFlag(tv, THV_KILL)) { - PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); + SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } diff --git a/src/counters.c b/src/counters.c index c8862240d8..4551a7a9c5 100644 --- a/src/counters.c +++ b/src/counters.c @@ -1,7 +1,8 @@ -#include "eidps-common.h" - -#include "time.h" +/** Copyright (c) 2009 Open Information Security Foundation. + * \author Anoop Saldanha + */ +#include "eidps-common.h" #include "eidps.h" #include "counters.h" #include "threadvars.h" @@ -12,111 +13,105 @@ #include "util-debug.h" /** \todo Get the default log directory from some global resource. */ -#define DEFAULT_LOG_FILENAME "stats.log" +#define SC_PERF_DEFAULT_LOG_FILENAME "stats.log" -static PerfOPIfaceContext *perf_op_ctx = NULL; +static SCPerfOPIfaceContext *sc_perf_op_ctx = NULL; /** * \brief Get the filename with path to the stats log file. * - * This function returns a string containing the log filename. It - * uses allocated memory simply to drop into the existing code a - * little better where a strdup was used. So as before, it is up to - * the caller to free the memory. + * This function returns a string containing the log filename. It uses + * allocated memory simply to drop into the existing code a little better + * where a strdup was used. So as before, it is up to the caller to free + * the memory. * - * \retval An allocated string containing the log filename or NULL on - * a failure. + * \retval An allocated string containing the log filename on success or NULL on + * failure. */ -static char * -PerfGetLogFilename(void) +static char *SCPerfGetLogFilename(void) { - char *log_dir; - char *log_filename; + char *log_dir = NULL; + char *log_filename = NULL; if (ConfGet("default-log-dir", &log_dir) != 1) log_dir = DEFAULT_LOG_DIR; - log_filename = malloc(PATH_MAX); - if (log_filename == NULL) - return NULL; - snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, DEFAULT_LOG_FILENAME); - return log_filename; -} + if ( (log_filename = malloc(PATH_MAX)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } -/** - * \brief Initializes the perf counter api. Things are hard coded currently. - * More work to be done when we implement multiple interfaces - */ -void PerfInitCounterApi(void) -{ - PerfInitOPCtx(); + if (snprintf(log_filename, PATH_MAX, "%s/%s", log_dir, + SC_PERF_DEFAULT_LOG_FILENAME) < 0) { + SCLogError(SC_SPRINTF_ERROR, "Sprintf Error"); + return NULL; + } - return; + return log_filename; } /** * \brief Initializes the output interface context + * + * \todo Support multiple interfaces */ -void PerfInitOPCtx(void) +static void SCPerfInitOPCtx(void) { - if ( (perf_op_ctx = malloc(sizeof(PerfOPIfaceContext))) == NULL) { - printf("error allocating memory\n"); - exit(0); + if ( (sc_perf_op_ctx = malloc(sizeof(SCPerfOPIfaceContext))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); } - memset(perf_op_ctx, 0, sizeof(PerfOPIfaceContext)); + memset(sc_perf_op_ctx, 0, sizeof(SCPerfOPIfaceContext)); - perf_op_ctx->iface = IFACE_FILE; + sc_perf_op_ctx->iface = SC_PERF_IFACE_FILE; - if ( (perf_op_ctx->file = PerfGetLogFilename()) == NULL) { - printf("error allocating memory\n"); - exit(0); + if ( (sc_perf_op_ctx->file = SCPerfGetLogFilename()) == NULL) { + SCLogInfo("Error retrieving Perf Counter API output file path"); + sc_perf_op_ctx->file = NULL; } - if ( (perf_op_ctx->fp = fopen(perf_op_ctx->file, "w+")) == NULL) { - printf("fopen error opening file %s\n", perf_op_ctx->file); - exit(0); + if ( (sc_perf_op_ctx->fp = fopen(sc_perf_op_ctx->file, "w+")) == NULL) { + SCLogError(SC_ERR_OPENING_FILE, "fopen error opening file %s\n", + sc_perf_op_ctx->file); + sc_perf_op_ctx->fp = stdout; } /* club the counter from multiple instances of the tm before o/p */ - perf_op_ctx->club_tm = 1; + sc_perf_op_ctx->club_tm = 1; - /* init the lock used by PerfClubTMInst */ - if (pthread_mutex_init(&perf_op_ctx->pctmi_lock, NULL) != 0) { - printf("error initializing the pctmi mutex\n"); - exit(0); + /* init the lock used by SCPerfClubTMInst */ + if (pthread_mutex_init(&sc_perf_op_ctx->pctmi_lock, NULL) != 0) { + SCLogError(SC_INITIALIZATION_ERROR, "error initializing pctmi mutex"); + exit(EXIT_FAILURE); } return; } /** - * \brief Spawns the wakeup, and the management thread + * \brief Releases the resources alloted to the output context of the Perf + * Counter API */ -void PerfSpawnThreads(void) +static void SCPerfReleaseOPCtx() { - ThreadVars *tv_wakeup = NULL; - ThreadVars *tv_mgmt = NULL; + if (sc_perf_op_ctx != NULL) { + if (sc_perf_op_ctx->fp != NULL) + fclose(sc_perf_op_ctx->fp); - /* Spawn the stats wakeup thread */ - tv_wakeup = TmThreadCreateMgmtThread("PerfWakeupThread", PerfWakeupThread, 1); - if (tv_wakeup == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(1); - } - if (TmThreadSpawn(tv_wakeup) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(1); - } + if (sc_perf_op_ctx->file != NULL) + free(sc_perf_op_ctx->file); - /* Spawn the stats mgmt thread */ - tv_mgmt = TmThreadCreateMgmtThread("PerfMgmtThread", PerfMgmtThread, 1); - if (tv_mgmt == NULL) { - printf("ERROR: TmThreadsCreate failed\n"); - exit(1); - } - if (TmThreadSpawn(tv_mgmt) != TM_ECODE_OK) { - printf("ERROR: TmThreadSpawn failed\n"); - exit(1); + if (sc_perf_op_ctx->pctmi != NULL) { + if (sc_perf_op_ctx->pctmi->tm_name != NULL) + free(sc_perf_op_ctx->pctmi->tm_name); + + if (sc_perf_op_ctx->pctmi->head != NULL) + free(sc_perf_op_ctx->pctmi->head); + + free(sc_perf_op_ctx->pctmi); + } + + free(sc_perf_op_ctx); } return; @@ -127,15 +122,18 @@ void PerfSpawnThreads(void) * performance stats information. * * \param arg is NULL always + * + * \retval NULL This is the value that is always returned */ -void * PerfMgmtThread(void *arg) +static void *SCPerfMgmtThread(void *arg) { ThreadVars *tv_local = (ThreadVars *)arg; uint8_t run = 1; struct timespec cond_time; - if (perf_op_ctx == NULL) { - printf("error: PerfInitCounterApi() has to be called first\n"); + if (sc_perf_op_ctx == NULL) { + SCLogError(SC_INVALID_ARGUMENTS, "SCPerfInitCounterApi() has to be " + "called first"); return NULL; } @@ -143,14 +141,14 @@ void * PerfMgmtThread(void *arg) while (run) { TmThreadTestThreadUnPaused(tv_local); - cond_time.tv_sec = time(NULL) + MGMTT_TTS; + cond_time.tv_sec = time(NULL) + SC_PERF_MGMTT_TTS; cond_time.tv_nsec = 0; pthread_mutex_lock(tv_local->m); pthread_cond_timedwait(tv_local->cond, tv_local->m, &cond_time); pthread_mutex_unlock(tv_local->m); - PerfOutputCounters(); + SCPerfOutputCounters(); if (TmThreadsCheckFlag(tv_local, THV_KILL)) { TmThreadsSetFlag(tv_local, THV_CLOSED); @@ -163,11 +161,13 @@ void * PerfMgmtThread(void *arg) /** * \brief Wake up thread. This thread wakes up every TTS(time to sleep) seconds - * and sets the flag for every ThreadVars' PerfContext + * and sets the flag for every ThreadVars' SCPerfContext * * \param arg is NULL always + * + * \retval NULL This is the value that is always returned */ -void * PerfWakeupThread(void *arg) +static void *SCPerfWakeupThread(void *arg) { ThreadVars *tv_local = (ThreadVars *)arg; uint8_t run = 1; @@ -179,18 +179,16 @@ void * PerfWakeupThread(void *arg) while (run) { TmThreadTestThreadUnPaused(tv_local); - cond_time.tv_sec = time(NULL) + WUT_TTS; + cond_time.tv_sec = time(NULL) + SC_PERF_WUT_TTS; cond_time.tv_nsec = 0; pthread_mutex_lock(tv_local->m); pthread_cond_timedwait(tv_local->cond, tv_local->m, &cond_time); pthread_mutex_unlock(tv_local->m); - // sleep(WUT_TTS); - tv = tv_root[TVT_PPT]; while (tv != NULL) { - if (tv->inq == NULL || tv->pctx.head == NULL) { + if (tv->inq == NULL || tv->sc_perf_pctx.head == NULL) { tv = tv->next; continue; } @@ -198,8 +196,8 @@ void * PerfWakeupThread(void *arg) q = &trans_q[tv->inq->id]; /* assuming the assignment of an int to be atomic, and even if it's - not, it should be okay */ - tv->pctx.perf_flag = 1; + * not, it should be okay */ + tv->sc_perf_pctx.perf_flag = 1; pthread_cond_signal(&q->cond_q); @@ -216,34 +214,59 @@ void * PerfWakeupThread(void *arg) } /** - * \brief Registers a counter + * \brief Parses a time based counter interval * - * \param cname Counter name to be registered - * \param tm_name Thread module name - * \param type Datatype of this counter variable - * \param desc Description of this counter - * \param pctx PerfContext for this tm-tv instance - * \param type_q Qualifier describing the counter to be registered + * \param pc Pointer to the PerfCounter that has to be updated with the + * interval + * \param interval Pointer to a character string that holds the time interval + */ +static void SCPerfParseTBCounterInterval(SCPerfCounter *pc, char *interval) +{ + char *temp_interval = NULL; + char *substr = NULL; + + if ( (temp_interval = strdup(interval)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } + + return; +} + +/** + * \brief Registers a counter. Used internally by the Perf Counter API + * + * \param cname Name of the counter, to be registered + * \param tm_name Thread module to which this counter belongs + * \param type Datatype of this counter variable + * \param desc Description of this counter + * \param pctx SCPerfContext for this tm-tv instance + * \param type_q Qualifier describing the type of counter to be registered + * \param interval Time interval required by a SC_PERF_TYPE_Q_TIMEBASED counter * - * \retval the counter id + * \retval the counter id for the newly registered counter, or the already + * present counter on success + * \retval 0 on failure */ -static uint16_t PerfRegisterQualifiedCounter(char *cname, char *tm_name, - int type, char *desc, - PerfContext *pctx, int type_q) +static uint16_t SCPerfRegisterQualifiedCounter(char *cname, char *tm_name, + int type, char *desc, + SCPerfContext *pctx, int type_q, + char *interval) { - PerfCounter **head = &pctx->head; - PerfCounter *temp = NULL; - PerfCounter *prev = NULL; - PerfCounter *pc = NULL; + SCPerfCounter **head = &pctx->head; + SCPerfCounter *temp = NULL; + SCPerfCounter *prev = NULL; + SCPerfCounter *pc = NULL; if (cname == NULL || tm_name == NULL || pctx == NULL) { - SCLogDebug("counter name, tm name null or PerfContext NULL"); + SCLogDebug("Counter name, tm name null or SCPerfContext NULL"); return 0; } - /* (TYPE_MAX - 1) because we still haven't implemented TYPE_STR */ - if ((type >= (TYPE_MAX - 1)) || (type < 0)) { - printf("Error: Counters of type %" PRId32 " can't be registered\n", type); + /* (SC_PERF_TYPE_MAX - 1) because we haven't implemented SC_PERF_TYPE_STR */ + if ((type >= (SC_PERF_TYPE_MAX - 1)) || (type < 0)) { + SCLogError(SC_INVALID_ARGUMENTS, "Counters of type %" PRId32 " can't " + "be registered", type); return 0; } @@ -252,8 +275,9 @@ static uint16_t PerfRegisterQualifiedCounter(char *cname, char *tm_name, prev = temp; if (strcmp(cname, temp->name->cname) == 0 && - strcmp(tm_name, temp->name->tm_name) == 0) + strcmp(tm_name, temp->name->tm_name) == 0) { break; + } temp = temp->next; } @@ -262,388 +286,599 @@ static uint16_t PerfRegisterQualifiedCounter(char *cname, char *tm_name, if (temp != NULL) return(temp->id); - if ( (pc = malloc(sizeof(PerfCounter))) == NULL) { - printf("error allocating memory\n"); - exit(0); + if ( (pc = malloc(sizeof(SCPerfCounter))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); } - memset(pc, 0, sizeof(PerfCounter)); + memset(pc, 0, sizeof(SCPerfCounter)); - if (prev == NULL) { + if (prev == NULL) *head = pc; - } else prev->next = pc; - if( (pc->name = malloc(sizeof(PerfCounterName))) == NULL) { - printf("error allocating memory. aborting\n"); + if ( (pc->name = malloc(sizeof(SCPerfCounterName))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); free(pc); - exit(0); + exit(EXIT_FAILURE); } - memset(pc->name, 0, sizeof(PerfCounterName)); + memset(pc->name, 0, sizeof(SCPerfCounterName)); - if ( (pc->value = malloc(sizeof(PerfCounterValue))) == NULL) { - printf("error allocating memory. aborting\n"); + if ( (pc->value = malloc(sizeof(SCPerfCounterValue))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); free(pc->name); free(pc); - exit(0); + exit(EXIT_FAILURE); } - memset(pc->value, 0, sizeof(PerfCounterValue)); + memset(pc->value, 0, sizeof(SCPerfCounterValue)); - pc->name->cname = strdup(cname); - pc->name->tm_name = strdup(tm_name); - pc->name->tid = pthread_self(); + if ( (pc->name->cname = strdup(cname)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } + + if ( (pc->name->tm_name = strdup(tm_name)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } + /* allocate memory to hold this counter value */ pc->value->type = type; - switch(pc->value->type) { - case TYPE_UINT64: + switch (pc->value->type) { + case SC_PERF_TYPE_UINT64: pc->value->size = sizeof(uint64_t); + break; - case TYPE_DOUBLE: + case SC_PERF_TYPE_DOUBLE: pc->value->size = sizeof(double); + break; } + if ( (pc->value->cvalue = malloc(pc->value->size)) == NULL) { - printf("error allocating memory\n"); - exit(0); + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); } memset(pc->value->cvalue, 0, pc->value->size); - /* assign a unique id to this PerfCounter. The id is local to this tv. - please note that the ids start from 1 and not 0 */ + /* assign a unique id to this SCPerfCounter. The id is local to this + * PerfContext. please note that the id start from 1, and not 0 */ pc->id = ++(pctx->curr_id); - if (desc != NULL) - pc->desc = strdup(desc); + if (desc != NULL && (pc->desc = strdup(desc)) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } pc->type_q = type_q; + /* handle timebased counters */ + if (pc->type_q & SC_PERF_TYPE_Q_TIMEBASED) + SCPerfParseTBCounterInterval(pc, interval); + + /* the display flag which specifies whether the counter should be displayed + * or not */ pc->disp = 1; return pc->id; } -uint16_t PerfTVRegisterCounter(char *cname, struct ThreadVars_ *tv, int type, - char *desc) -{ - return PerfRegisterQualifiedCounter(cname, tv->name, type, desc, - &tv->pctx, TYPE_Q_NORMAL); -} - -uint16_t PerfTVRegisterAvgCounter(char *cname, struct ThreadVars_ *tv, - int type, char *desc) -{ - return PerfRegisterQualifiedCounter(cname, tv->name, type, desc, - &tv->pctx, TYPE_Q_AVERAGE); -} - -uint16_t PerfTVRegisterMaxCounter(char *cname, struct ThreadVars_ *tv, - int type, char *desc) -{ - return PerfRegisterQualifiedCounter(cname, tv->name, type, desc, - &tv->pctx, TYPE_Q_MAXIMUM); -} - -uint16_t PerfRegisterCounter(char *cname, char *tm_name, int type, char *desc, - PerfContext *pctx) -{ - return PerfRegisterQualifiedCounter(cname, tm_name, type, desc, - pctx, TYPE_Q_NORMAL); -} - -uint16_t PerfRegisterAvgCounter(char *cname, char *tm_name, int type, - char *desc, PerfContext *pctx) -{ - return PerfRegisterQualifiedCounter(cname, tm_name, type, desc, - pctx, TYPE_Q_AVERAGE); -} - -uint16_t PerfRegisterMaxCounter(char *cname, char *tm_name, int type, - char *desc, PerfContext *pctx) -{ - return PerfRegisterQualifiedCounter(cname, tm_name, type, desc, - pctx, TYPE_Q_MAXIMUM); -} - /** - * \brief Allows the user the set whether the counter identified with the id - * should be displayed or not in the output - * - * \param id Id of the counter - * \param pctx Pointer to the PerfContext in which the counter exists - * \param disp Holds a 0 or a non-zero value, based on whether the counter - * should be displayed or not in the output + * \brief Releases a perf counter. Used internally by + * SCPerfReleaseSCPerfCounterS() * - * \retval 1 on success, 0 on failure + * \param pc Pointer to the SCPerfCounter to be freed */ -int PerfCounterDisplay(uint16_t id, PerfContext *pctx, int disp) +static void SCPerfReleaseCounter(SCPerfCounter *pc) { - PerfCounter *pc = NULL; - - if (pctx == NULL) { -#ifdef DEBUG - printf("pctx null inside PerfCounterDisplay\n"); -#endif - return 0; - } - - if ( (id < 1) || (id > pctx->curr_id) ) { -#ifdef DEBUG - printf("counter with the id %d doesn't exist in this tm instance", id); -#endif - return 0; - } + if (pc != NULL) { + if (pc->name != NULL) { + if (pc->name->cname != NULL) + free(pc->name->cname); - pc = pctx->head; - while(pc->id != id) - pc = pc->next; + if (pc->name->tm_name != NULL) + free(pc->name->tm_name); - pc->disp = (disp != 0); + free(pc->name); + } - return 1; -} + if (pc->value != NULL) { + if (pc->value->cvalue != NULL) + free(pc->value->cvalue); -/** - * \brief Increments the local counter - * - * \param id Index of the counter in the counter array - * \param pca Counter array that holds the local counters for this TM - */ -inline void PerfCounterIncr(uint16_t id, PerfCounterArray *pca) -{ - if (pca == NULL) { - SCLogDebug("counterarray is NULL"); - return; - } - if ((id < 1) || (id > pca->size)) { - SCLogDebug("counter doesn't exist"); - return; - } + free(pc->value); + } - switch (pca->head[id].pc->value->type) { - case TYPE_UINT64: - pca->head[id].ui64_cnt++; - break; - case TYPE_DOUBLE: - pca->head[id].d_cnt++; - break; - } + if (pc->desc != NULL) + free(pc->desc); - if (pca->head[id].syncs == ULONG_MAX) { - pca->head[id].syncs = 0; - pca->head[id].wrapped_syncs++; + free(pc); } - pca->head[id].syncs++; return; } /** - * \brief Adds a value of type uint64_t to the local counter. + * \brief Copies the SCPerfCounter value from the local counter present in the + * SCPerfCounterArray to its corresponding global counterpart. Used + * internally by SCPerfUpdateCounterArray() * - * \param id ID of the counter as set by the API - * \param pca Counter array that holds the local counter for this TM - * \param x Value to add to this local counter + * \param pcae Pointer to the SCPerfCounterArray which holds the local + * versions of the counters + * \param reset_lc Flag which indicates if the values of the local counters + * in the SCPerfCounterArray has to be reset or not */ -inline void PerfCounterAddUI64(uint16_t id, PerfCounterArray *pca, uint64_t x) +static void SCPerfCopyCounterValue(SCPCAElem *pcae, int reset_lc) { - if (!pca) { -#ifdef DEBUG - printf("counterarray is NULL\n"); -#endif - return; - } - if ((id < 1) || (id > pca->size)) { -#ifdef DEBUG - printf("counter doesn't exist\n"); -#endif - return; - } + SCPerfCounter *pc = NULL; + double d_temp = 0; + uint64_t ui64_temp = 0; + int i = 0; - switch (pca->head[id].pc->value->type) { - case TYPE_UINT64: - pca->head[id].ui64_cnt += x; - break; - case TYPE_DOUBLE: - pca->head[id].d_cnt += x; - break; - } + pc = pcae->pc; + switch (pc->value->type) { + case SC_PERF_TYPE_UINT64: + ui64_temp = pcae->ui64_cnt; - if (pca->head[id].syncs == ULONG_MAX) { - pca->head[id].syncs = 0; - pca->head[id].wrapped_syncs++; - } - pca->head[id].syncs++; + if (pc->type_q & SC_PERF_TYPE_Q_AVERAGE) { + for (i = 0; i < pcae->wrapped_syncs; i++) + ui64_temp /= ULONG_MAX; - return; -} + if (pcae->syncs != 0) + ui64_temp /= pcae->syncs; + } + memcpy(pc->value->cvalue, &ui64_temp, pc->value->size); -/** - * \brief Adds a value of type double to the local counter - * - * \param id ID of the counter as set by the API - * \param pca Counter array that holds the local counter for this TM - * \param x Value to add to this local counter - */ -inline void PerfCounterAddDouble(uint16_t id, PerfCounterArray *pca, double x) -{ - if (!pca) { -#ifdef DEBUG - printf("counterarray is NULL\n"); -#endif - return; - } - if ((id < 1) || (id > pca->size)) { -#ifdef DEBUG - printf("counter doesn't exist\n"); -#endif - return; - } + if (reset_lc) + pcae->ui64_cnt = 0; - /* incase you are trying to add a double to a counter of type TYPE_UINT64 - it will be truncated */ - switch (pca->head[id].pc->value->type) { - case TYPE_UINT64: - pca->head[id].ui64_cnt += x; - break; - case TYPE_DOUBLE: - pca->head[id].d_cnt += x; break; - } - - if (pca->head[id].syncs == ULONG_MAX) { - pca->head[id].syncs = 0; - pca->head[id].wrapped_syncs++; - } - pca->head[id].syncs++; + case SC_PERF_TYPE_DOUBLE: + d_temp = pcae->d_cnt; - return; -} + if (pc->type_q & SC_PERF_TYPE_Q_AVERAGE) { + for (i = 0; i < pcae->wrapped_syncs; i++) + d_temp /= ULONG_MAX; -/** - * \brief Sets a local counter to an arg of type double - * - * \param id Index of the local counter in the counter array - * \param pca Pointer to the PerfCounterArray - * \param x The value to set for the counter - */ -inline void PerfCounterSetUI64(uint16_t id, PerfCounterArray *pca, - uint64_t x) -{ - if (!pca) { -#ifdef DEBUG - printf("counterarray is NULL\n"); -#endif - return; - } + if (pcae->syncs != 0) + d_temp /= pcae->syncs; + } + memcpy(pc->value->cvalue, &d_temp, pc->value->size); - if ((id < 1) || (id > pca->size)) { -#ifdef DEBUG - printf("counter doesn't exist\n"); -#endif - return; - } + if (reset_lc) + pcae->d_cnt = 0; - switch (pca->head[id].pc->value->type) { - case TYPE_UINT64: - if (pca->head[id].pc->type_q & TYPE_Q_MAXIMUM) { - if (x > pca->head[id].ui64_cnt) - pca->head[id].ui64_cnt = x; - } else if (pca->head[id].pc->type_q & TYPE_Q_NORMAL) - pca->head[id].ui64_cnt = x; break; - case TYPE_DOUBLE: - if (pca->head[id].pc->type_q & TYPE_Q_MAXIMUM) { - if (x > pca->head[id].d_cnt) - pca->head[id].d_cnt = x; - } else if (pca->head[id].pc->type_q & TYPE_Q_NORMAL) - pca->head[id].d_cnt = x; - break; - } - - if (pca->head[id].syncs == ULONG_MAX) { - pca->head[id].syncs = 0; - pca->head[id].wrapped_syncs++; } - pca->head[id].syncs++; return; } /** - * \brief Sets a local counter to an arg of type double - * - * \param id Index of the local counter in the counter array - * \param pca Pointer to the PerfCounterArray - * \param x The value to set for the counter + * \brief The file output interface for the Perf Counter api */ -inline void PerfCounterSetDouble(uint16_t id, PerfCounterArray *pca, - double x) +static int SCPerfOutputCounterFileIface() { - if (!pca) { -#ifdef DEBUG - printf("counterarray is NULL\n"); -#endif - return; - } + ThreadVars *tv = NULL; + SCPerfClubTMInst *pctmi = NULL; + SCPerfCounter *pc = NULL; + SCPerfCounter **pc_heads = NULL; - if ((id < 1) || (id > pca->size)) { -#ifdef DEBUG - printf("counter doesn't exist\n"); -#endif - return; - } + uint64_t *ui64_cvalue = NULL; + uint64_t ui64_result = 0; - switch (pca->head[id].pc->value->type) { - case TYPE_UINT64: - if (pca->head[id].pc->type_q & TYPE_Q_MAXIMUM) { - if (x > pca->head[id].ui64_cnt) - pca->head[id].ui64_cnt = x; - } else if (pca->head[id].pc->type_q & TYPE_Q_NORMAL) - pca->head[id].ui64_cnt = x; - break; - case TYPE_DOUBLE: - if (pca->head[id].pc->type_q & TYPE_Q_MAXIMUM) { - if (x > pca->head[id].d_cnt) - pca->head[id].d_cnt = x; - } else if (pca->head[id].pc->type_q & TYPE_Q_NORMAL) - pca->head[id].d_cnt = x; - break; - } + double *double_cvalue = NULL; + double double_result = 0; - if (pca->head[id].syncs == ULONG_MAX) { - pca->head[id].syncs = 0; - pca->head[id].wrapped_syncs++; - } - pca->head[id].syncs++; + struct timeval tval; + struct tm *tms; - return; -} + int i = 0; + int flag = 0; -/** + if (sc_perf_op_ctx->fp == NULL) { + SCLogDebug("perf_op_ctx->fp is NULL"); + return 0; + } + + memset(&tval, 0, sizeof(struct timeval)); + + gettimeofday(&tval, NULL); + tms = (struct tm *)localtime(&tval.tv_sec); + + fprintf(sc_perf_op_ctx->fp, "----------------------------------------------" + "---------------------\n"); + fprintf(sc_perf_op_ctx->fp, "%" PRId32 "/%" PRId32 "/%04d -- %02d:%02d:%02d\n", + tms->tm_mday, tms->tm_mon, tms->tm_year + 1900, tms->tm_hour, + tms->tm_min, tms->tm_sec); + fprintf(sc_perf_op_ctx->fp, "----------------------------------------------" + "---------------------\n"); + fprintf(sc_perf_op_ctx->fp, "%-25s | %-25s | %-s\n", "Counter", "TM Name", + "Value"); + fprintf(sc_perf_op_ctx->fp, "----------------------------------------------" + "---------------------\n"); + + if (sc_perf_op_ctx->club_tm == 0) { + for (i = 0; i < TVT_MAX; i++) { + tv = tv_root[i]; + + while (tv != NULL) { + pthread_mutex_lock(&tv->sc_perf_pctx.m); + pc = tv->sc_perf_pctx.head; + + while (pc != NULL) { + if (pc->disp == 0) { + pc = pc->next; + continue; + } + + ui64_cvalue = (uint64_t *)pc->value->cvalue; + fprintf(sc_perf_op_ctx->fp, "%-25s | %-25s | %-" PRIu64 "\n", + pc->name->cname, pc->name->tm_name, *ui64_cvalue); + + pc = pc->next; + } + + pthread_mutex_unlock(&tv->sc_perf_pctx.m); + tv = tv->next; + } + fflush(sc_perf_op_ctx->fp); + } + + return 1; + } + + pctmi = sc_perf_op_ctx->pctmi; + while (pctmi != NULL) { + if ( (pc_heads = malloc(pctmi->size * sizeof(SCPerfCounter *))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); + } + memset(pc_heads, 0, pctmi->size * sizeof(SCPerfCounter **)); + + for (i = 0; i < pctmi->size; i++) { + pc_heads[i] = pctmi->head[i]->head; + + pthread_mutex_lock(&pctmi->head[i]->m); + + while(strcmp(pctmi->tm_name, pc_heads[i]->name->tm_name)) + pc_heads[i] = pc_heads[i]->next; + } + + flag = 1; + while(flag) { + ui64_result = 0; + double_result = 0; + pc = pc_heads[0]; + + for (i = 0; i < pctmi->size; i++) { + switch (pc->value->type) { + case SC_PERF_TYPE_UINT64: + ui64_cvalue = pc_heads[i]->value->cvalue; + ui64_result += *ui64_cvalue; + + break; + case SC_PERF_TYPE_DOUBLE: + double_cvalue = pc_heads[i]->value->cvalue; + double_result += *double_cvalue; + + break; + } + + pc_heads[i] = pc_heads[i]->next; + + if (pc_heads[i] == NULL || + strcmp(pctmi->tm_name, pc_heads[0]->name->tm_name)) + flag = 0; + } + + if (pc->disp == 0) + continue; + + switch (pc->value->type) { + case SC_PERF_TYPE_UINT64: + fprintf(sc_perf_op_ctx->fp, "%-25s | %-25s | %-" PRIu64 "\n", + pc->name->cname, pctmi->tm_name, ui64_result); + + break; + case SC_PERF_TYPE_DOUBLE: + fprintf(sc_perf_op_ctx->fp, "%-25s | %-25s | %-lf\n", + pc->name->cname, pctmi->tm_name, double_result); + + break; + } + } + + for (i = 0; i < pctmi->size; i++) + pthread_mutex_unlock(&pctmi->head[i]->m); + + pctmi = pctmi->next; + + free(pc_heads); + + fflush(sc_perf_op_ctx->fp); + } + + return 1; +} + +/** + * \brief Initializes the perf counter api. Things are hard coded currently. + * More work to be done when we implement multiple interfaces + */ +void SCPerfInitCounterApi(void) +{ + SCPerfInitOPCtx(); + + return; +} + +/** + * \brief Spawns the wakeup, and the management thread used by the perf + * counter api + */ +void SCPerfSpawnThreads(void) +{ + ThreadVars *tv_wakeup = NULL; + ThreadVars *tv_mgmt = NULL; + + /* Spawn the stats wakeup thread */ + tv_wakeup = TmThreadCreateMgmtThread("SCPerfWakeupThread", + SCPerfWakeupThread, 1); + if (tv_wakeup == NULL) { + SCLogError(SC_ERR_THREAD_CREATE_ERROR, "TmThreadCreateMgmtThread " + "failed"); + exit(EXIT_FAILURE); + } + if (TmThreadSpawn(tv_wakeup) != 0) { + SCLogError(SC_THREAD_SPAWN_FAILED, "TmThreadSpawn failed for " + "SCPerfWakeupThread"); + exit(EXIT_FAILURE); + } + + /* Spawn the stats mgmt thread */ + tv_mgmt = TmThreadCreateMgmtThread("SCPerfMgmtThread", + SCPerfMgmtThread, 1); + if (tv_mgmt == NULL) { + SCLogError(SC_ERR_THREAD_CREATE_ERROR, + "TmThreadCreateMgmtThread failed"); + exit(EXIT_FAILURE); + } + if (TmThreadSpawn(tv_mgmt) != 0) { + SCLogError(SC_THREAD_SPAWN_FAILED, "TmThreadSpawn failed for " + "SCPerfWakeupThread"); + exit(EXIT_FAILURE); + } + + return; +} + +/** + * \brief Registers a normal, unqualified counter + * + * \param cname Name of the counter, to be registered + * \param tv Pointer to the ThreadVars instance for which the counter would + * be registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * + * \retval id Counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfTVRegisterCounter(char *cname, struct ThreadVars_ *tv, int type, + char *desc) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tv->name, type, desc, + &tv->sc_perf_pctx, + SC_PERF_TYPE_Q_NORMAL, NULL); + + return id; +} + +/** + * \brief Registers a counter, whose value holds the average of all the values + * assigned to it. + * + * \param cname Name of the counter, to be registered + * \param tv Pointer to the ThreadVars instance for which the counter would + * be registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * + * \retval id Counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfTVRegisterAvgCounter(char *cname, struct ThreadVars_ *tv, + int type, char *desc) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tv->name, type, desc, + &tv->sc_perf_pctx, + SC_PERF_TYPE_Q_AVERAGE, NULL); + + return id; +} + +/** + * \brief Registers a counter, whose value holds the maximum of all the values + * assigned to it. + * + * \param cname Name of the counter, to be registered + * \param tv Pointer to the ThreadVars instance for which the counter would + * be registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * + * \retval the counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfTVRegisterMaxCounter(char *cname, struct ThreadVars_ *tv, + int type, char *desc) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tv->name, type, desc, + &tv->sc_perf_pctx, + SC_PERF_TYPE_Q_MAXIMUM, NULL); + + return id; +} + +/** + * \brief Registers a counter, whose value holds the value taken held the + * counter in a specified time interval + * + * \param cname Name of the counter, to be registered + * \param tv Pointer to the ThreadVars instance for which the counter + * would be registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * \param interval The time interval over which the counter value has to be + * calculated. The format for the time interval is + * "", where number > 0, and modifier can + * be "s" for seconds, "m" for minutes, "h" for hours + * + * \retval id Counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfTVRegisterIntervalCounter(char *cname, struct ThreadVars_ *tv, + int type, char *desc, + char *time_interval) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tv->name, type, desc, + &tv->sc_perf_pctx, + SC_PERF_TYPE_Q_MAXIMUM, + time_interval); + + return id; +} + +/** + * \brief Registers a normal, unqualified counter + * + * \param cname Name of the counter, to be registered + * \param tm_name Name of the engine module under which the counter has to be + * registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * \param pctx SCPerfContext corresponding to the tm_name key under which the + * key has to be registered + * + * \retval id Counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfRegisterCounter(char *cname, char *tm_name, int type, char *desc, + SCPerfContext *pctx) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tm_name, type, desc, + pctx, SC_PERF_TYPE_Q_NORMAL, + NULL); + + return id; +} + +/** + * \brief Registers a counter, whose value holds the average of all the values + * assigned to it. + * + * \param cname Name of the counter, to be registered + * \param tm_name Name of the engine module under which the counter has to be + * registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * \param pctx SCPerfContext corresponding to the tm_name key under which the + * key has to be registered + * + * \retval id Counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfRegisterAvgCounter(char *cname, char *tm_name, int type, + char *desc, SCPerfContext *pctx) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tm_name, type, desc, + pctx, SC_PERF_TYPE_Q_AVERAGE, + NULL); + + return id; +} + +/** + * \brief Registers a counter, whose value holds the maximum of all the values + * assigned to it. + * + * \param cname Name of the counter, to be registered + * \param tm_name Name of the engine module under which the counter has to be + * registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * \param pctx SCPerfContext corresponding to the tm_name key under which the + * key has to be registered + * + * \retval id Counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfRegisterMaxCounter(char *cname, char *tm_name, int type, + char *desc, SCPerfContext *pctx) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tm_name, type, desc, + pctx, SC_PERF_TYPE_Q_MAXIMUM, + NULL); + + return id; +} + +/** + * \brief Registers a counter, whose value holds the value taken held the + * counter in a specified time interval + * + * \param cname Name of the counter, to be registered + * \param tm_name Name of the engine module under which the counter has to be + * registered + * \param type Datatype of this counter variable + * \param desc Description of this counter + * \param pctx SCPerfContext corresponding to the tm_name key under which the + * key has to be registered + * \param interval The time interval over which the counter value has to be + * calculated. The format for the time interval is + * "", where number > 0, and modifier can + * be "s" for seconds, "m" for minutes, "h" for hours + * + * \retval id Counter id for the newly registered counter, or the already + * present counter + */ +uint16_t SCPerfRegisterIntervalCounter(char *cname, char *tm_name, int type, + char *desc, SCPerfContext *pctx, + char *time_interval) +{ + uint16_t id = SCPerfRegisterQualifiedCounter(cname, tm_name, type, desc, + pctx, SC_PERF_TYPE_Q_MAXIMUM, + time_interval); + + return id; +} + +/** * \brief Adds a TM to the clubbed TM table. Multiple instances of the same TM * are stacked together in a PCTMI container * * \param tm_name Name of the tm to be added to the table - * \param pctx PerfContext associated with the TM tm_name + * \param pctx SCPerfContext associated with the TM tm_name * * \retval 1 on success, 0 on failure */ -int PerfAddToClubbedTMTable(char *tm_name, PerfContext *pctx) +int SCPerfAddToClubbedTMTable(char *tm_name, SCPerfContext *pctx) { - PerfClubTMInst *pctmi = NULL; - PerfClubTMInst *prev = NULL; - PerfClubTMInst *temp = NULL; - PerfContext **hpctx; + SCPerfClubTMInst *pctmi = NULL; + SCPerfClubTMInst *prev = NULL; + SCPerfClubTMInst *temp = NULL; + SCPerfContext **hpctx = NULL; int i = 0; if (tm_name == NULL || pctx == NULL) { - SCLogDebug("supplied argument(s) to PerfAddToClubbedTMTable NULL"); + SCLogDebug("supplied argument(s) to SCPerfAddToClubbedTMTable NULL"); return 0; } - pthread_mutex_lock(&perf_op_ctx->pctmi_lock); + pthread_mutex_lock(&sc_perf_op_ctx->pctmi_lock); - pctmi = perf_op_ctx->pctmi; + pctmi = sc_perf_op_ctx->pctmi; prev = pctmi; while (pctmi != NULL) { @@ -656,23 +891,23 @@ int PerfAddToClubbedTMTable(char *tm_name, PerfContext *pctx) } if (pctmi == NULL) { - if ( (temp = malloc(sizeof(PerfClubTMInst))) == NULL) { - printf("error allocating memory\n"); + if ( (temp = malloc(sizeof(SCPerfClubTMInst))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); exit(0); } - memset(temp, 0, sizeof(PerfClubTMInst)); + memset(temp, 0, sizeof(SCPerfClubTMInst)); temp->size++; - temp->head = realloc(temp->head, temp->size * sizeof(PerfContext **)); + temp->head = realloc(temp->head, temp->size * sizeof(SCPerfContext **)); temp->head[0] = pctx; temp->tm_name = strdup(tm_name); if (prev == NULL) - perf_op_ctx->pctmi = temp; + sc_perf_op_ctx->pctmi = temp; else prev->next = temp; - pthread_mutex_unlock(&perf_op_ctx->pctmi_lock); + pthread_mutex_unlock(&sc_perf_op_ctx->pctmi_lock); return 1; } @@ -681,12 +916,12 @@ int PerfAddToClubbedTMTable(char *tm_name, PerfContext *pctx) if (hpctx[i] != pctx) continue; - pthread_mutex_unlock(&perf_op_ctx->pctmi_lock); + pthread_mutex_unlock(&sc_perf_op_ctx->pctmi_lock); return 1; } - pctmi->head = realloc(pctmi->head, (pctmi->size + 1) * - sizeof(PerfContext **)); + pctmi->head = realloc(pctmi->head, + (pctmi->size + 1) * sizeof(SCPerfContext **)); hpctx = pctmi->head; hpctx[pctmi->size] = pctx; @@ -700,26 +935,25 @@ int PerfAddToClubbedTMTable(char *tm_name, PerfContext *pctx) } pctmi->size++; - pthread_mutex_unlock(&perf_op_ctx->pctmi_lock); + pthread_mutex_unlock(&sc_perf_op_ctx->pctmi_lock); return 1; } - /** * \brief Returns a counter array for counters in this id range(s_id - e_id) * * \param s_id Counter id of the first counter to be added to the array * \param e_id Counter id of the last counter to be added to the array - * \param pctx Pointer to the tv's PerfContext + * \param pctx Pointer to the tv's SCPerfContext * * \retval a counter-array in this(s_id-e_id) range for this TM instance */ -PerfCounterArray * PerfGetCounterArrayRange(uint16_t s_id, uint16_t e_id, - PerfContext *pctx) +SCPerfCounterArray *SCPerfGetCounterArrayRange(uint16_t s_id, uint16_t e_id, + SCPerfContext *pctx) { - PerfCounter *pc = NULL; - PerfCounterArray *pca = NULL; + SCPerfCounter *pc = NULL; + SCPerfCounterArray *pca = NULL; uint32_t i = 0; if (pctx == NULL) { @@ -742,17 +976,17 @@ PerfCounterArray * PerfGetCounterArrayRange(uint16_t s_id, uint16_t e_id, return NULL; } - if ( (pca = malloc(sizeof(PerfCounterArray))) == NULL) { - printf("Error allocating memory\n"); - exit(0); + if ( (pca = malloc(sizeof(SCPerfCounterArray))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); } - memset(pca, 0, sizeof(PerfCounterArray)); + memset(pca, 0, sizeof(SCPerfCounterArray)); - if ( (pca->head = malloc(sizeof(PCAElem) * (e_id - s_id + 2))) == NULL) { - printf("Error allocating memory\n"); - exit(0); + if ( (pca->head = malloc(sizeof(SCPCAElem) * (e_id - s_id + 2))) == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + exit(EXIT_FAILURE); } - memset(pca->head, 0, sizeof(PCAElem) * (e_id - s_id + 2)); + memset(pca->head, 0, sizeof(SCPCAElem) * (e_id - s_id + 2)); pc = pctx->head; while (pc->id != s_id) @@ -774,414 +1008,373 @@ PerfCounterArray * PerfGetCounterArrayRange(uint16_t s_id, uint16_t e_id, * \brief Returns a counter array for all counters registered for this tm * instance * - * \param pctx Pointer to the tv's PerfContext + * \param pctx Pointer to the tv's SCPerfContext * * \retval a counter-array for all counters of this tm instance */ -PerfCounterArray * PerfGetAllCountersArray(PerfContext *pctx) +SCPerfCounterArray *SCPerfGetAllCountersArray(SCPerfContext *pctx) { - return((pctx)?PerfGetCounterArrayRange(1, pctx->curr_id, pctx):NULL); + return ((pctx)? SCPerfGetCounterArrayRange(1, pctx->curr_id, pctx): NULL); } - /** - * \brief Updates an individual counter + * \brief Allows the user the set whether the counter identified with the id + * should be displayed or not in the output * - * \param cname Name of the counter to be synced - * \param tm_name Thread module name - * \param id holds Counter id of the counter to be synced - * \param value Pointer to the local counter from the client thread - * \param pctx PerfContext for this tm-tv instance + * \param id Id of the counter + * \param pctx Pointer to the SCPerfContext in which the counter exists + * \param disp Holds a 0 or a non-zero value, based on whether the counter + * should be displayed or not, in the output * * \retval 1 on success, 0 on failure */ -int PerfUpdateCounter(char *cname, char *tm_name, u_int64_t id, void *value, - PerfContext *pctx) +int SCPerfCounterDisplay(uint16_t id, SCPerfContext *pctx, int disp) { - PerfCounter *pc = NULL; + SCPerfCounter *pc = NULL; if (pctx == NULL) { -#ifdef DEBUG - printf("pctx null inside PerfUpdateCounter\n"); -#endif - return 0; - } - - if ((cname == NULL || tm_name == NULL) && (id > pctx->curr_id || id < 1)) { -#ifdef DEBUG - printf("id supplied doesn't exist. Please supply cname and " - "tm_name instead\n"); -#endif + SCLogDebug("pctx null inside SCPerfCounterDisplay"); return 0; } - if (value == NULL) { -#ifdef DEBUG - printf("Pointer to counter(value) supplied to PerfUpdateCounter is " - "NULL\n"); -#endif + if ( (id < 1) || (id > pctx->curr_id) ) { + SCLogDebug("counter with the id %d doesn't exist in this tm instance", + id); return 0; } pc = pctx->head; - while(pc != NULL) { - if (pc->id != id) { - pc = pc->next; - continue; - } - - memcpy(pc->value->cvalue, value, pc->value->size); - pc->updated++; - - break; - } + while(pc->id != id) + pc = pc->next; - if (pc == NULL) { -#ifdef DEBUG - printf("this counter isn't registered in this tm\n"); -#endif - return 0; - } + pc->disp = (disp != 0); return 1; } -static void PerfCopyCounterValue(PCAElem *pcae, int reset_lc) +/** + * \brief Increments the local counter + * + * \param id Index of the counter in the counter array + * \param pca Counter array that holds the local counters for this TM + */ +inline void SCPerfCounterIncr(uint16_t id, SCPerfCounterArray *pca) { - PerfCounter *pc = NULL; - double d_temp = 0; - uint64_t ui64_temp = 0; - int i = 0; + if (pca == NULL) { + SCLogDebug("counterarray is NULL"); + return; + } + if ((id < 1) || (id > pca->size)) { + SCLogDebug("counter doesn't exist"); + return; + } - pc = pcae->pc; - switch (pc->value->type) { - case TYPE_UINT64: - ui64_temp = pcae->ui64_cnt; - if (pc->type_q & TYPE_Q_AVERAGE) { - for (i = 0; i < pcae->wrapped_syncs; i++) - ui64_temp /= ULONG_MAX; + switch (pca->head[id].pc->value->type) { + case SC_PERF_TYPE_UINT64: + pca->head[id].ui64_cnt++; + break; + case SC_PERF_TYPE_DOUBLE: + pca->head[id].d_cnt++; + break; + } - if (pcae->syncs != 0) - ui64_temp /= pcae->syncs; - } - memcpy(pc->value->cvalue, &ui64_temp, pc->value->size); - - if (reset_lc) - pcae->ui64_cnt = 0; - - break; - case TYPE_DOUBLE: - d_temp = pcae->d_cnt; - if (pc->type_q & TYPE_Q_AVERAGE) { - for (i = 0; i < pcae->wrapped_syncs; i++) - d_temp /= ULONG_MAX; - - if (pcae->syncs != 0) - d_temp /= pcae->syncs; - } - memcpy(pc->value->cvalue, &d_temp, pc->value->size); - - if (reset_lc) - pcae->d_cnt = 0; - - break; - } + if (pca->head[id].syncs == ULONG_MAX) { + pca->head[id].syncs = 0; + pca->head[id].wrapped_syncs++; + } + pca->head[id].syncs++; return; } /** - * \brief Syncs the counter array with the global counter variables + * \brief Adds a value of type uint64_t to the local counter. * - * \param pca Pointer to the PerfCounterArray - * \param pctx Pointer the the tv's PerfContext - * \param reset_lc Indicates whether the local counter has to be reset or not + * \param id ID of the counter as set by the API + * \param pca Counter array that holds the local counter for this TM + * \param x Value to add to this local counter */ -int PerfUpdateCounterArray(PerfCounterArray *pca, PerfContext *pctx, - int reset_lc) +inline void SCPerfCounterAddUI64(uint16_t id, SCPerfCounterArray *pca, uint64_t x) { - PerfCounter *pc = NULL; - PCAElem *pcae = NULL; - uint32_t i = 0; - - if (pca == NULL || pctx == NULL) { - SCLogDebug("pca or pctx is NULL inside PerfUpdateCounterArray"); - return -1; + if (!pca) { + SCLogDebug("counterarray is NULL"); + return; + } + if ((id < 1) || (id > pca->size)) { + SCLogDebug("counter doesn't exist"); + return; } - pc = pctx->head; - pcae = pca->head; - - pthread_mutex_lock(&pctx->m); - for (i = 1; i <= pca->size; i++) { - while (pc != NULL) { - if (pc->id != pcae[i].id) { - pc = pc->next; - continue; - } - - PerfCopyCounterValue(&pcae[i], reset_lc); - - pc->updated++; - - pc = pc->next; + switch (pca->head[id].pc->value->type) { + case SC_PERF_TYPE_UINT64: + pca->head[id].ui64_cnt += x; + break; + case SC_PERF_TYPE_DOUBLE: + pca->head[id].d_cnt += x; break; - } } - pthread_mutex_unlock(&pctx->m); - pctx->perf_flag = 0; + if (pca->head[id].syncs == ULONG_MAX) { + pca->head[id].syncs = 0; + pca->head[id].wrapped_syncs++; + } + pca->head[id].syncs++; - return 1; + return; } /** - * \brief The output interface dispatcher for the counter api + * \brief Adds a value of type double to the local counter + * + * \param id ID of the counter as set by the API + * \param pca Counter array that holds the local counter for this TM + * \param x Value to add to this local counter */ -void PerfOutputCounters() +inline void SCPerfCounterAddDouble(uint16_t id, SCPerfCounterArray *pca, double x) { - switch (perf_op_ctx->iface) { - case IFACE_FILE: - PerfOutputCounterFileIface(); - break; - case IFACE_CONSOLE: - // yet to be implemented - break; - case IFACE_NETWORK: - // yet to be implemented + if (!pca) { + SCLogDebug("counterarray is NULL"); + return; + } + if ((id < 1) || (id > pca->size)) { + SCLogDebug("counter doesn't exist"); + return; + } + + /* incase you are trying to add a double to a counter of type SC_PERF_TYPE_UINT64 + * it will be truncated */ + switch (pca->head[id].pc->value->type) { + case SC_PERF_TYPE_UINT64: + pca->head[id].ui64_cnt += x; break; - case IFACE_SYSLOG: - // yet to be implemented + case SC_PERF_TYPE_DOUBLE: + pca->head[id].d_cnt += x; break; } + if (pca->head[id].syncs == ULONG_MAX) { + pca->head[id].syncs = 0; + pca->head[id].wrapped_syncs++; + } + pca->head[id].syncs++; + return; } /** - * \brief The file output interface for the counter api + * \brief Sets a value of type double to the local counter + * + * \param id Index of the local counter in the counter array + * \param pca Pointer to the SCPerfCounterArray + * \param x The value to set for the counter */ -int PerfOutputCounterFileIface() +inline void SCPerfCounterSetUI64(uint16_t id, SCPerfCounterArray *pca, + uint64_t x) { - ThreadVars *tv = NULL; - PerfClubTMInst *pctmi = NULL; - PerfCounter *pc = NULL; - PerfCounter **pc_heads; - - uint64_t *ui64_cvalue = NULL; - uint64_t ui64_result = 0; - - double *double_cvalue = NULL; - double double_result = 0; + if (!pca) { + SCLogDebug("counterarray is NULL"); + return; + } + if ((id < 1) || (id > pca->size)) { + SCLogDebug("counter doesn't exist"); + return; + } - struct timeval tval; - struct tm *tms; + switch (pca->head[id].pc->value->type) { + case SC_PERF_TYPE_UINT64: + if ( (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_MAXIMUM) && + (x > pca->head[id].ui64_cnt)) { + pca->head[id].ui64_cnt = x; + } else if (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_NORMAL) { + pca->head[id].ui64_cnt = x; + } - int i; - int flag; + break; + case SC_PERF_TYPE_DOUBLE: + if ( (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_MAXIMUM) && + (x > pca->head[id].d_cnt)) { + pca->head[id].d_cnt = x; + } else if (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_NORMAL) { + pca->head[id].d_cnt = x; + } - if (perf_op_ctx->fp == NULL) { -#ifdef DEBUG - printf("perf_op_ctx->fp is NULL"); -#endif - return 0; + break; } - memset(&tval, 0, sizeof(struct timeval)); - - gettimeofday(&tval, NULL); - tms = (struct tm *)localtime(&tval.tv_sec); - - fprintf(perf_op_ctx->fp, "-------------------------------------------------" - "------------------\n"); - fprintf(perf_op_ctx->fp, "%" PRId32 "/%" PRId32 "/%04d -- %02d:%02d:%02d\n", tms->tm_mday, - tms->tm_mon, tms->tm_year + 1900, tms->tm_hour, tms->tm_min, - tms->tm_sec); - fprintf(perf_op_ctx->fp, "-------------------------------------------------" - "------------------\n"); - fprintf(perf_op_ctx->fp, "%-25s | %-25s | %-s\n", "Counter", "TM Name", - "Value"); - fprintf(perf_op_ctx->fp, "-------------------------------------------------" - "------------------\n"); + if (pca->head[id].syncs == ULONG_MAX) { + pca->head[id].syncs = 0; + pca->head[id].wrapped_syncs++; + } + pca->head[id].syncs++; - if (perf_op_ctx->club_tm == 0) { - for (i = 0; i < TVT_MAX; i++) { - tv = tv_root[i]; + return; +} - while (tv != NULL) { - pthread_mutex_lock(&tv->pctx.m); - pc = tv->pctx.head; +/** + * \brief Sets a local counter to an arg of type double + * + * \param id Index of the local counter in the counter array + * \param pca Pointer to the SCPerfCounterArray + * \param x The value to set for the counter + */ +inline void SCPerfCounterSetDouble(uint16_t id, SCPerfCounterArray *pca, + double x) +{ + if (!pca) { + SCLogDebug("counterarray is NULL"); + return; + } - while (pc != NULL) { - if (pc->disp == 0) { - pc = pc->next; - continue; - } + if ((id < 1) || (id > pca->size)) { + SCLogDebug("counter doesn't exist"); + return; + } - ui64_cvalue = (uint64_t *)pc->value->cvalue; - fprintf(perf_op_ctx->fp, "%-25s | %-25s | %-" PRIu64 "\n", - pc->name->cname, pc->name->tm_name, *ui64_cvalue); -#ifdef DEBUG - printf("%-10" PRIuMAX " %-10" PRIu16 " %-10s %-" PRIu64 "\n", (uintmax_t)pc->name->tid, pc->id, - pc->name->cname, *ui64_cvalue); -#endif - pc = pc->next; - } + switch (pca->head[id].pc->value->type) { + case SC_PERF_TYPE_UINT64: + if ( (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_MAXIMUM) && + (x > pca->head[id].ui64_cnt)) { + pca->head[id].ui64_cnt = x; + } else if (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_NORMAL) { + pca->head[id].ui64_cnt = x; + } - pthread_mutex_unlock(&tv->pctx.m); - tv = tv->next; + break; + case SC_PERF_TYPE_DOUBLE: + if ( (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_MAXIMUM) && + (x > pca->head[id].d_cnt)) { + pca->head[id].d_cnt = x; + } else if (pca->head[id].pc->type_q & SC_PERF_TYPE_Q_NORMAL) { + pca->head[id].d_cnt = x; } - fflush(perf_op_ctx->fp); - } - return 1; + break; } - pctmi = perf_op_ctx->pctmi; - while (pctmi != NULL) { - if ( (pc_heads = malloc(pctmi->size * sizeof(PerfCounter *))) == NULL) { - printf("error allocating memory\n"); - exit(0); - } - memset(pc_heads, 0, pctmi->size * sizeof(PerfCounter **)); + if (pca->head[id].syncs == ULONG_MAX) { + pca->head[id].syncs = 0; + pca->head[id].wrapped_syncs++; + } + pca->head[id].syncs++; - for (i = 0; i < pctmi->size; i++) { - pc_heads[i] = pctmi->head[i]->head; + return; +} - pthread_mutex_lock(&pctmi->head[i]->m); +/** + * \brief Syncs the counter array with the global counter variables + * + * \param pca Pointer to the SCPerfCounterArray + * \param pctx Pointer the the tv's SCPerfContext + * \param reset_lc Indicates whether the local counter has to be reset or not + * + * \retval 0 on success + * \retval -1 on error + */ +int SCPerfUpdateCounterArray(SCPerfCounterArray *pca, SCPerfContext *pctx, + int reset_lc) +{ + SCPerfCounter *pc = NULL; + SCPCAElem *pcae = NULL; + uint32_t i = 0; - while(strcmp(pctmi->tm_name, pc_heads[i]->name->tm_name)) - pc_heads[i] = pc_heads[i]->next; - } + if (pca == NULL || pctx == NULL) { + SCLogDebug("pca or pctx is NULL inside SCPerfUpdateCounterArray"); + return -1; + } - flag = 1; - while(flag) { - ui64_result = 0; - double_result = 0; - pc = pc_heads[0]; - for (i = 0; i < pctmi->size; i++) { - switch (pc->value->type) { - case TYPE_UINT64: - ui64_cvalue = pc_heads[i]->value->cvalue; - ui64_result += *ui64_cvalue; - break; - case TYPE_DOUBLE: - double_cvalue = pc_heads[i]->value->cvalue; - double_result += *double_cvalue; - break; - } + pcae = pca->head; - pc_heads[i] = pc_heads[i]->next; + pthread_mutex_lock(&pctx->m); + pc = pctx->head; - if (pc_heads[i] == NULL || - strcmp(pctmi->tm_name, pc_heads[0]->name->tm_name)) - flag = 0; + for (i = 1; i <= pca->size; i++) { + while (pc != NULL) { + if (pc->id != pcae[i].id) { + pc = pc->next; + continue; } - if (pc->disp == 0) - continue; + SCPerfCopyCounterValue(&pcae[i], reset_lc); - switch (pc->value->type) { - case TYPE_UINT64: - fprintf(perf_op_ctx->fp, "%-25s | %-25s | %-" PRIu64 "\n", - pc->name->cname, pctmi->tm_name, ui64_result); - break; - case TYPE_DOUBLE: - fprintf(perf_op_ctx->fp, "%-25s | %-25s | %-lf\n", - pc->name->cname, pctmi->tm_name, double_result); - break; - } -#ifdef DEBUG - /** \todo XXX "result" no longer exists */ -#if 0 - printf("%-25s | %-25s | %-" PRIu64 "\n", pc->name->cname, - pctmi->tm_name, result); -#endif -#endif + pc->updated++; + + pc = pc->next; + break; } - for (i = 0; i < pctmi->size; i++) - pthread_mutex_unlock(&pctmi->head[i]->m); + } - pctmi = pctmi->next; - free(pc_heads); + pthread_mutex_unlock(&pctx->m); - fflush(perf_op_ctx->fp); - } + pctx->perf_flag = 0; return 1; } /** - * \brief Releases perf api resources. + * \brief The output interface dispatcher for the counter api */ -void PerfReleaseResources() +void SCPerfOutputCounters() { - PerfReleaseOPCtx(); + switch (sc_perf_op_ctx->iface) { + case SC_PERF_IFACE_FILE: + SCPerfOutputCounterFileIface(); - return; -} + break; + case SC_PERF_IFACE_CONSOLE: + /* yet to be implemented */ -void PerfReleaseOPCtx() -{ - if (perf_op_ctx != NULL) { - if (perf_op_ctx->fp != NULL) - fclose(perf_op_ctx->fp); - - if (perf_op_ctx->file != NULL) - free(perf_op_ctx->file); - - if (perf_op_ctx->pctmi != NULL) { - if (perf_op_ctx->pctmi->tm_name != NULL) - free(perf_op_ctx->pctmi->tm_name); - if (perf_op_ctx->pctmi->head != NULL) - free(perf_op_ctx->pctmi->head); - free(perf_op_ctx->pctmi); - } + break; + case SC_PERF_IFACE_SYSLOG: + /* yet to be implemented */ - free(perf_op_ctx); + break; } return; } -void PerfReleasePerfCounterS(PerfCounter *head) +/** + * \brief Releases the resources alloted by the Perf Counter API + */ +void SCPerfReleaseResources() { - PerfCounter *pc = NULL; - - while (head != NULL) { - pc = head; - head = head->next; - PerfReleaseCounter(pc); - } + SCPerfReleaseOPCtx(); return; } -void PerfReleaseCounter(PerfCounter *pc) +/** + * \brief Releases a list of perf counters + * + * \param head Pointer to the head of the list of perf counters that have to + * be freed + */ +void SCPerfReleaseSCPerfCounterS(SCPerfCounter *head) { - if (pc != NULL) { - if (pc->name != NULL) { - if (pc->name->cname != NULL) free(pc->name->cname); - if (pc->name->tm_name != NULL) free(pc->name->tm_name); - free(pc->name); - } - if (pc->value != NULL) { - if (pc->value->cvalue != NULL) free(pc->value->cvalue); - free(pc->value); - } - if (pc->desc != NULL) free(pc->desc); - free(pc); + SCPerfCounter *pc = NULL; + + while (head != NULL) { + pc = head; + head = head->next; + SCPerfReleaseCounter(pc); } return; } -void PerfReleasePCA(PerfCounterArray *pca) +/** + * \brief Releases the SCPerfCounterArray allocated by the user, for storing and + * updating local counter values + * + * \param pca Pointer to the SCPerfCounterArray + */ +void SCPerfReleasePCA(SCPerfCounterArray *pca) { if (pca != NULL) { if (pca->head != NULL) free(pca->head); + free(pca); } @@ -1189,74 +1382,75 @@ void PerfReleasePCA(PerfCounterArray *pca) } -//------------------------------------Unit_Tests-------------------------------- +/*----------------------------------Unit_Tests--------------------------------*/ -static int PerfTestCounterReg01() +static int SCPerfTestCounterReg01() { - PerfContext pctx; + SCPerfContext pctx; - memset(&pctx, 0, sizeof(PerfContext)); + memset(&pctx, 0, sizeof(SCPerfContext)); - return PerfRegisterCounter("t1", "c1", 5, NULL, &pctx); + return SCPerfRegisterCounter("t1", "c1", 5, NULL, &pctx); } -static int PerfTestCounterReg02() +static int SCPerfTestCounterReg02() { - PerfContext pctx; + SCPerfContext pctx; - memset(&pctx, 0, sizeof(PerfContext)); + memset(&pctx, 0, sizeof(SCPerfContext)); - return PerfRegisterCounter(NULL, NULL, TYPE_UINT64, NULL, &pctx); + return SCPerfRegisterCounter(NULL, NULL, SC_PERF_TYPE_UINT64, NULL, &pctx); } -static int PerfTestCounterReg03() +static int SCPerfTestCounterReg03() { - PerfContext pctx; + SCPerfContext pctx; int result; - memset(&pctx, 0, sizeof(PerfContext)); + memset(&pctx, 0, sizeof(SCPerfContext)); - result = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &pctx); + result = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, &pctx); - PerfReleasePerfCounterS(pctx.head); + SCPerfReleaseSCPerfCounterS(pctx.head); return result; } -static int PerfTestCounterReg04() +static int SCPerfTestCounterReg04() { - PerfContext pctx; + SCPerfContext pctx; int result; - memset(&pctx, 0, sizeof(PerfContext)); + memset(&pctx, 0, sizeof(SCPerfContext)); - PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &pctx); - PerfRegisterCounter("t2", "c2", TYPE_UINT64, NULL, &pctx); - PerfRegisterCounter("t3", "c3", TYPE_UINT64, NULL, &pctx); + SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, &pctx); + SCPerfRegisterCounter("t2", "c2", SC_PERF_TYPE_UINT64, NULL, &pctx); + SCPerfRegisterCounter("t3", "c3", SC_PERF_TYPE_UINT64, NULL, &pctx); - result = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &pctx); + result = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, &pctx); - PerfReleasePerfCounterS(pctx.head); + SCPerfReleaseSCPerfCounterS(pctx.head); return result; } -static int PerfTestGetCntArray05() +static int SCPerfTestGetCntArray05() { ThreadVars tv; int id; memset(&tv, 0, sizeof(ThreadVars)); - id = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &tv.pctx); + id = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - tv.pca = PerfGetAllCountersArray(NULL); + tv.sc_perf_pca = SCPerfGetAllCountersArray(NULL); - return (!tv.pca)?1:0; + return (!tv.sc_perf_pca)?1:0; } -static int PerfTestGetCntArray06() +static int SCPerfTestGetCntArray06() { ThreadVars tv; int id; @@ -1264,100 +1458,109 @@ static int PerfTestGetCntArray06() memset(&tv, 0, sizeof(ThreadVars)); - id = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &tv.pctx); + id = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - tv.pca = PerfGetAllCountersArray(&tv.pctx); + tv.sc_perf_pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - result = (tv.pca)?1:0; + result = (tv.sc_perf_pca)?1:0; - PerfReleasePerfCounterS(tv.pctx.head); - PerfReleasePCA(tv.pca); + SCPerfReleaseSCPerfCounterS(tv.sc_perf_pctx.head); + SCPerfReleasePCA(tv.sc_perf_pca); return result; } -static int PerfTestCntArraySize07() +static int SCPerfTestCntArraySize07() { ThreadVars tv; - PerfCounterArray *pca = NULL; + SCPerfCounterArray *pca = NULL; int result; memset(&tv, 0, sizeof(ThreadVars)); - pca = (PerfCounterArray *)&tv.pca; + pca = (SCPerfCounterArray *)&tv.sc_perf_pca; - PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &tv.pctx); - PerfRegisterCounter("t2", "c2", TYPE_UINT64, NULL, &tv.pctx); + SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + SCPerfRegisterCounter("t2", "c2", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - pca = PerfGetAllCountersArray(&tv.pctx); + pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - PerfCounterIncr(1, pca); - PerfCounterIncr(2, pca); + SCPerfCounterIncr(1, pca); + SCPerfCounterIncr(2, pca); result = pca->size; - PerfReleasePerfCounterS(tv.pctx.head); - PerfReleasePCA(pca); + SCPerfReleaseSCPerfCounterS(tv.sc_perf_pctx.head); + SCPerfReleasePCA(pca); return result; } -static int PerfTestUpdateCounter08() +static int SCPerfTestUpdateCounter08() { ThreadVars tv; - PerfCounterArray *pca = NULL; + SCPerfCounterArray *pca = NULL; int id; int result; memset(&tv, 0, sizeof(ThreadVars)); - id = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &tv.pctx); + id = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - pca = PerfGetAllCountersArray(&tv.pctx); + pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - PerfCounterIncr(id, pca); - PerfCounterAddUI64(id, pca, 100); + SCPerfCounterIncr(id, pca); + SCPerfCounterAddUI64(id, pca, 100); result = pca->head[id].ui64_cnt; - PerfReleasePerfCounterS(tv.pctx.head); - PerfReleasePCA(pca); + SCPerfReleaseSCPerfCounterS(tv.sc_perf_pctx.head); + SCPerfReleasePCA(pca); return result; } -static int PerfTestUpdateCounter09() +static int SCPerfTestUpdateCounter09() { ThreadVars tv; - PerfCounterArray *pca = NULL; + SCPerfCounterArray *pca = NULL; uint16_t id1, id2; int result; memset(&tv, 0, sizeof(ThreadVars)); - id1 = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &tv.pctx); - PerfRegisterCounter("t2", "c2", TYPE_UINT64, NULL, &tv.pctx); - PerfRegisterCounter("t3", "c3", TYPE_UINT64, NULL, &tv.pctx); - PerfRegisterCounter("t4", "c4", TYPE_UINT64, NULL, &tv.pctx); - id2 = PerfRegisterCounter("t5", "c5", TYPE_UINT64, NULL, &tv.pctx); + id1 = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + SCPerfRegisterCounter("t2", "c2", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + SCPerfRegisterCounter("t3", "c3", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + SCPerfRegisterCounter("t4", "c4", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + id2 = SCPerfRegisterCounter("t5", "c5", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - pca = PerfGetAllCountersArray(&tv.pctx); + pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - PerfCounterIncr(id2, pca); - PerfCounterAddUI64(id2, pca, 100); + SCPerfCounterIncr(id2, pca); + SCPerfCounterAddUI64(id2, pca, 100); result = (pca->head[id1].ui64_cnt == 0) && (pca->head[id2].ui64_cnt == 101); - PerfReleasePerfCounterS(tv.pctx.head); - PerfReleasePCA(pca); + SCPerfReleaseSCPerfCounterS(tv.sc_perf_pctx.head); + SCPerfReleasePCA(pca); return result; } -static int PerfTestUpdateGlobalCounter10() +static int SCPerfTestUpdateGlobalCounter10() { ThreadVars tv; - PerfCounterArray *pca = NULL; + SCPerfCounterArray *pca = NULL; int result = 1; uint16_t id1, id2, id3; @@ -1365,38 +1568,41 @@ static int PerfTestUpdateGlobalCounter10() memset(&tv, 0, sizeof(ThreadVars)); - id1 = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &tv.pctx); - id2 = PerfRegisterCounter("t2", "c2", TYPE_UINT64, NULL, &tv.pctx); - id3 = PerfRegisterCounter("t3", "c3", TYPE_UINT64, NULL, &tv.pctx); + id1 = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + id2 = SCPerfRegisterCounter("t2", "c2", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + id3 = SCPerfRegisterCounter("t3", "c3", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - pca = PerfGetAllCountersArray(&tv.pctx); + pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - PerfCounterIncr(id1, pca); - PerfCounterAddUI64(id2, pca, 100); - PerfCounterIncr(id3, pca); - PerfCounterAddUI64(id3, pca, 100); + SCPerfCounterIncr(id1, pca); + SCPerfCounterAddUI64(id2, pca, 100); + SCPerfCounterIncr(id3, pca); + SCPerfCounterAddUI64(id3, pca, 100); - PerfUpdateCounterArray(pca, &tv.pctx, 0); + SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0); - p = (uint64_t *)tv.pctx.head->value->cvalue; + p = (uint64_t *)tv.sc_perf_pctx.head->value->cvalue; result = (1 == *p); - p = (uint64_t *)tv.pctx.head->next->value->cvalue; + p = (uint64_t *)tv.sc_perf_pctx.head->next->value->cvalue; result &= (100 == *p); - p = (uint64_t *)tv.pctx.head->next->next->value->cvalue; + p = (uint64_t *)tv.sc_perf_pctx.head->next->next->value->cvalue; result &= (101 == *p); - PerfReleasePerfCounterS(tv.pctx.head); - PerfReleasePCA(pca); + SCPerfReleaseSCPerfCounterS(tv.sc_perf_pctx.head); + SCPerfReleasePCA(pca); return result; } -static int PerfTestCounterValues11() +static int SCPerfTestCounterValues11() { ThreadVars tv; - PerfCounterArray *pca = NULL; + SCPerfCounterArray *pca = NULL; int result = 1; uint16_t id1, id2, id3, id4; @@ -1404,54 +1610,58 @@ static int PerfTestCounterValues11() memset(&tv, 0, sizeof(ThreadVars)); - id1 = PerfRegisterCounter("t1", "c1", TYPE_UINT64, NULL, &tv.pctx); - id2 = PerfRegisterCounter("t2", "c2", TYPE_UINT64, NULL, &tv.pctx); - id3 = PerfRegisterCounter("t3", "c3", TYPE_UINT64, NULL, &tv.pctx); - id4 = PerfRegisterCounter("t4", "c4", TYPE_UINT64, NULL, &tv.pctx); + id1 = SCPerfRegisterCounter("t1", "c1", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + id2 = SCPerfRegisterCounter("t2", "c2", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + id3 = SCPerfRegisterCounter("t3", "c3", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); + id4 = SCPerfRegisterCounter("t4", "c4", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - pca = PerfGetAllCountersArray(&tv.pctx); + pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - PerfCounterIncr(id1, pca); - PerfCounterAddUI64(id2, pca, 256); - PerfCounterAddUI64(id3, pca, 257); - PerfCounterAddUI64(id4, pca, 16843024); + SCPerfCounterIncr(id1, pca); + SCPerfCounterAddUI64(id2, pca, 256); + SCPerfCounterAddUI64(id3, pca, 257); + SCPerfCounterAddUI64(id4, pca, 16843024); - PerfUpdateCounterArray(pca, &tv.pctx, 0); + SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0); - u8p = (uint8_t *)tv.pctx.head->value->cvalue; + u8p = (uint8_t *)tv.sc_perf_pctx.head->value->cvalue; result &= (1 == *u8p); result &= (0 == *(u8p + 1)); result &= (0 == *(u8p + 2)); result &= (0 == *(u8p + 3)); - u8p = (uint8_t *)tv.pctx.head->next->value->cvalue; + u8p = (uint8_t *)tv.sc_perf_pctx.head->next->value->cvalue; result &= (0 == *u8p); result &= (1 == *(u8p + 1)); result &= (0 == *(u8p + 2)); result &= (0 == *(u8p + 3)); - u8p = (uint8_t *)tv.pctx.head->next->next->value->cvalue; + u8p = (uint8_t *)tv.sc_perf_pctx.head->next->next->value->cvalue; result &= (1 == *u8p); result &= (1 == *(u8p + 1)); result &= (0 == *(u8p + 2)); result &= (0 == *(u8p + 3)); - u8p = (uint8_t *)tv.pctx.head->next->next->next->value->cvalue; + u8p = (uint8_t *)tv.sc_perf_pctx.head->next->next->next->value->cvalue; result &= (16 == *u8p); result &= (1 == *(u8p + 1)); result &= (1 == *(u8p + 2)); result &= (1 == *(u8p + 3)); - PerfReleasePerfCounterS(tv.pctx.head); - PerfReleasePCA(pca); + SCPerfReleaseSCPerfCounterS(tv.sc_perf_pctx.head); + SCPerfReleasePCA(pca); return result; } -static int PerfTestAverageQual12() +static int SCPerfTestAverageQual12() { ThreadVars tv; - PerfCounterArray *pca = NULL; + SCPerfCounterArray *pca = NULL; uint64_t *ui64_temp = NULL; double *d_temp = NULL; @@ -1460,48 +1670,50 @@ static int PerfTestAverageQual12() memset(&tv, 0, sizeof(ThreadVars)); - id1 = PerfRegisterAvgCounter("t1", "c1", TYPE_DOUBLE, NULL, &tv.pctx); - id2 = PerfRegisterAvgCounter("t2", "c2", TYPE_UINT64, NULL, &tv.pctx); + id1 = SCPerfRegisterAvgCounter("t1", "c1", SC_PERF_TYPE_DOUBLE, NULL, + &tv.sc_perf_pctx); + id2 = SCPerfRegisterAvgCounter("t2", "c2", SC_PERF_TYPE_UINT64, NULL, + &tv.sc_perf_pctx); - pca = PerfGetAllCountersArray(&tv.pctx); + pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - PerfCounterAddDouble(id1, pca, 1); - PerfCounterAddDouble(id1, pca, 2); - PerfCounterAddDouble(id1, pca, 3); - PerfCounterAddDouble(id1, pca, 4); - PerfCounterAddDouble(id1, pca, 5); - PerfCounterAddDouble(id1, pca, 6); + SCPerfCounterAddDouble(id1, pca, 1); + SCPerfCounterAddDouble(id1, pca, 2); + SCPerfCounterAddDouble(id1, pca, 3); + SCPerfCounterAddDouble(id1, pca, 4); + SCPerfCounterAddDouble(id1, pca, 5); + SCPerfCounterAddDouble(id1, pca, 6); - PerfUpdateCounterArray(pca, &tv.pctx, 0); + SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0); result &= (21 == pca->head[1].d_cnt); result &= (6 == pca->head[1].syncs); result &= (0 == pca->head[1].wrapped_syncs); - d_temp = tv.pctx.head->value->cvalue; + d_temp = tv.sc_perf_pctx.head->value->cvalue; result &= (3.5 == *d_temp); - PerfCounterAddUI64(id2, pca, 1.635); - PerfCounterAddUI64(id2, pca, 2.12); - PerfCounterAddUI64(id2, pca, 3.74); - PerfCounterAddUI64(id2, pca, 4.23); - PerfCounterAddUI64(id2, pca, 5.76); - PerfCounterAddDouble(id2, pca, 6.99999); + SCPerfCounterAddUI64(id2, pca, 1.635); + SCPerfCounterAddUI64(id2, pca, 2.12); + SCPerfCounterAddUI64(id2, pca, 3.74); + SCPerfCounterAddUI64(id2, pca, 4.23); + SCPerfCounterAddUI64(id2, pca, 5.76); + SCPerfCounterAddDouble(id2, pca, 6.99999); - PerfUpdateCounterArray(pca, &tv.pctx, 0); + SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0); result &= (21 == pca->head[2].ui64_cnt); result &= (6 == pca->head[2].syncs); result &= (0 == pca->head[2].wrapped_syncs); - ui64_temp = tv.pctx.head->next->value->cvalue; + ui64_temp = tv.sc_perf_pctx.head->next->value->cvalue; result &= (3 == *ui64_temp); return result; } -static int PerfTestMaxQual13() +static int SCPerfTestMaxQual13() { ThreadVars tv; - PerfCounterArray *pca = NULL; + SCPerfCounterArray *pca = NULL; double *p; int result = 1; @@ -1509,53 +1721,54 @@ static int PerfTestMaxQual13() memset(&tv, 0, sizeof(ThreadVars)); - id1 = PerfRegisterMaxCounter("t1", "c1", TYPE_DOUBLE, NULL, &tv.pctx); + id1 = SCPerfRegisterMaxCounter("t1", "c1", SC_PERF_TYPE_DOUBLE, NULL, + &tv.sc_perf_pctx); - p = tv.pctx.head->value->cvalue; + p = tv.sc_perf_pctx.head->value->cvalue; - pca = PerfGetAllCountersArray(&tv.pctx); + pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx); - PerfCounterSetDouble(id1, pca, 1.352); - PerfCounterSetDouble(id1, pca, 5.12412); - PerfCounterSetDouble(id1, pca, 4.1234); - PerfCounterSetDouble(id1, pca, 5.13562); - PerfCounterSetDouble(id1, pca, 1.2342); + SCPerfCounterSetDouble(id1, pca, 1.352); + SCPerfCounterSetDouble(id1, pca, 5.12412); + SCPerfCounterSetDouble(id1, pca, 4.1234); + SCPerfCounterSetDouble(id1, pca, 5.13562); + SCPerfCounterSetDouble(id1, pca, 1.2342); - PerfUpdateCounterArray(pca, &tv.pctx, 0); + SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0); result &= (5.13562 == *p); - PerfCounterSetDouble(id1, pca, 8); - PerfCounterSetDouble(id1, pca, 7); + SCPerfCounterSetDouble(id1, pca, 8); + SCPerfCounterSetDouble(id1, pca, 7); - PerfUpdateCounterArray(pca, &tv.pctx, 0); + SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0); result &= (8 == *p); - PerfCounterSetDouble(id1, pca, 6); - PerfCounterSetUI64(id1, pca, 10); - PerfCounterSetDouble(id1, pca, 9.562); + SCPerfCounterSetDouble(id1, pca, 6); + SCPerfCounterSetUI64(id1, pca, 10); + SCPerfCounterSetDouble(id1, pca, 9.562); - PerfUpdateCounterArray(pca, &tv.pctx, 0); + SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0); result &= (10 == *p); return result; } -void PerfRegisterTests() +void SCPerfRegisterTests() { - UtRegisterTest("PerfTestCounterReg01", PerfTestCounterReg01, 0); - UtRegisterTest("PerfTestCounterReg02", PerfTestCounterReg02, 0); - UtRegisterTest("PerfTestCounterReg03", PerfTestCounterReg03, 1); - UtRegisterTest("PerfTestCounterReg04", PerfTestCounterReg04, 1); - UtRegisterTest("PerfTestGetCntArray05", PerfTestGetCntArray05, 1); - UtRegisterTest("PerfTestGetCntArray06", PerfTestGetCntArray06, 1); - UtRegisterTest("PerfTestCntArraySize07", PerfTestCntArraySize07, 2); - UtRegisterTest("PerfTestUpdateCounter08", PerfTestUpdateCounter08, 101); - UtRegisterTest("PerfTestUpdateCounter09", PerfTestUpdateCounter09, 1); - UtRegisterTest("PerfTestUpdateGlobalCounter10", - PerfTestUpdateGlobalCounter10, 1); - UtRegisterTest("PerfTestCounterValues11", PerfTestCounterValues11, 1); - UtRegisterTest("PerfTestAverageQual12", PerfTestAverageQual12, 1); - UtRegisterTest("PerfTestMaxQual13", PerfTestMaxQual13, 1); + UtRegisterTest("SCPerfTestCounterReg01", SCPerfTestCounterReg01, 0); + UtRegisterTest("SCPerfTestCounterReg02", SCPerfTestCounterReg02, 0); + UtRegisterTest("SCPerfTestCounterReg03", SCPerfTestCounterReg03, 1); + UtRegisterTest("SCPerfTestCounterReg04", SCPerfTestCounterReg04, 1); + UtRegisterTest("SCPerfTestGetCntArray05", SCPerfTestGetCntArray05, 1); + UtRegisterTest("SCPerfTestGetCntArray06", SCPerfTestGetCntArray06, 1); + UtRegisterTest("SCPerfTestCntArraySize07", SCPerfTestCntArraySize07, 2); + UtRegisterTest("SCPerfTestUpdateCounter08", SCPerfTestUpdateCounter08, 101); + UtRegisterTest("SCPerfTestUpdateCounter09", SCPerfTestUpdateCounter09, 1); + UtRegisterTest("SCPerfTestUpdateGlobalCounter10", + SCPerfTestUpdateGlobalCounter10, 1); + UtRegisterTest("SCPerfTestCounterValues11", SCPerfTestCounterValues11, 1); + UtRegisterTest("SCPerfTestAverageQual12", SCPerfTestAverageQual12, 1); + UtRegisterTest("SCPerfTestMaxQual13", SCPerfTestMaxQual13, 1); return; } diff --git a/src/counters.h b/src/counters.h index 6edc77d1b5..1d32fa2f7d 100644 --- a/src/counters.h +++ b/src/counters.h @@ -9,55 +9,71 @@ struct ThreadVars_; /* Time interval for syncing the local counters with the global ones */ -#define WUT_TTS 3 +#define SC_PERF_WUT_TTS 3 + /* Time interval at which the mgmt thread o/p the stats */ -#define MGMTT_TTS 8 +#define SC_PERF_MGMTT_TTS 8 -/* Type of counter */ +/** + * \brief Data type for different kind of Perf counters that can be registered + */ enum { - TYPE_UINT64, - TYPE_DOUBLE, - TYPE_STR, - TYPE_MAX, + SC_PERF_TYPE_UINT64, + SC_PERF_TYPE_DOUBLE, + SC_PERF_TYPE_STR, + SC_PERF_TYPE_MAX, }; -/* Qualifier for the counter */ +/** + * \brief Different kinds of qualifier that can be used to modify the behaviour + * of the Perf counter to be registered + */ enum { - TYPE_Q_NORMAL = 0x01, - TYPE_Q_AVERAGE = 0x02, - TYPE_Q_MAXIMUM = 0x04, - TYPE_Q_TIMEBASED = 0x08, - TYPE_Q_MAX = 0x10, + SC_PERF_TYPE_Q_NORMAL = 0x01, + SC_PERF_TYPE_Q_AVERAGE = 0x02, + SC_PERF_TYPE_Q_MAXIMUM = 0x04, + SC_PERF_TYPE_Q_TIMEBASED = 0x08, + SC_PERF_TYPE_Q_MAX = 0x10, }; -/* Output interfaces */ +/** + * \brief Different output interfaces made available by the Perf counter API + */ enum { - IFACE_FILE, - IFACE_CONSOLE, - IFACE_NETWORK, - IFACE_SYSLOG, + SC_PERF_IFACE_FILE, + SC_PERF_IFACE_CONSOLE, + SC_PERF_IFACE_SYSLOG, + SC_PERF_IFACE_MAX, }; -typedef struct PerfCounterName_ { +/** + * \brief Name of the counter. Basically like a primary key for a counter + */ +typedef struct SCPerfCounterName_ { char *cname; char *tm_name; - pthread_t tid; -} PerfCounterName; +} SCPerfCounterName; -typedef struct PerfCounterValue_ { +/** + * \brief Holds the counter value, type, and the size of the type + */ +typedef struct SCPerfCounterValue_ { void *cvalue; uint32_t size; uint32_t type; -} PerfCounterValue; +} SCPerfCounterValue; -/* Container to hold the counter variable */ -typedef struct PerfCounter_ { - PerfCounterName *name; - PerfCounterValue *value; +/** + * \brief Container to hold the counter variable + */ +typedef struct SCPerfCounter_ { + SCPerfCounterName *name; + SCPerfCounterValue *value; /* local id for this counter in this tm */ uint16_t id; + /* description of this counter */ char *desc; /* no of times the local counter has been synced with this counter */ @@ -70,25 +86,36 @@ typedef struct PerfCounter_ { int type_q; /* the next perfcounter for this tv's tm instance */ - struct PerfCounter_ *next; -} PerfCounter; + struct SCPerfCounter_ *next; +} SCPerfCounter; -/* Holds the Perf Context for a ThreadVars instance */ -typedef struct PerfContext_ { - PerfCounter *head; +/** + * \brief Holds the Perf Context for a ThreadVars instance + */ +typedef struct SCPerfContext_ { + /* pointer to the head of a list of counters assigned under this context */ + SCPerfCounter *head; /* flag set by the wakeup thread, to inform the client threads to sync */ uint32_t perf_flag; + + /* holds the total no of counters already assigned for this perf context */ uint16_t curr_id; /* mutex to prevent simultaneous access during update_counter/output_stat */ pthread_mutex_t m; -} PerfContext; +} SCPerfContext; + +/** + * \brief Node elements used by the SCPerfCounterArray(PCA) Node + */ +typedef struct SCPCAElem_ { + /* pointer to the PerfCounter that corresponds to this PCAElem */ + SCPerfCounter *pc; -/* PerfCounterArray(PCA) Node*/ -typedef struct PCAElem_ { - PerfCounter *pc; + /* counter id of the above counter(pc) */ uint16_t id; + union { uint64_t ui64_cnt; double d_cnt; @@ -99,106 +126,95 @@ typedef struct PCAElem_ { /* indicates the times syncs has overflowed */ uint64_t wrapped_syncs; -} PCAElem; +} SCPCAElem; -/* The PerfCounterArray */ -typedef struct PerfCounterArray_ { +/** + * \brief The SCPerfCounterArray used to hold the local version of the counters + * registered + */ +typedef struct SCPerfCounterArray_ { /* points to the array holding PCAElems */ - PCAElem *head; + SCPCAElem *head; /* no of PCAElems in head */ uint32_t size; -} PerfCounterArray; +} SCPerfCounterArray; -/* Holds multiple instances of the same TM together, used when the stats - * have to be clubbed based on TM, before being sent out*/ -typedef struct PerfClubTMInst_ { +/** + * \brief Holds multiple instances of the same TM together, used when the stats + * have to be clubbed based on TM, before being sent out + */ +typedef struct SCPerfClubTMInst_ { char *tm_name; - PerfContext **head; + SCPerfContext **head; uint32_t size; - struct PerfClubTMInst_ *next; -} PerfClubTMInst; + struct SCPerfClubTMInst_ *next; +} SCPerfClubTMInst; -/* Holds the output interface context for the counter api */ -typedef struct PerfOPIfaceContext_ { +/** + * \brief Holds the output interface context for the counter api + */ +typedef struct SCPerfOPIfaceContext_ { + /* the iface to be used for output */ uint32_t iface; + + /* the file to be used if the output interface used is SC_PERF_IFACE_FILE */ char *file; /* more interfaces to be supported later. For now just a file */ FILE *fp; + /* indicates whether the counter values from the same threading module + * should be clubbed or not, during output */ uint32_t club_tm; - PerfClubTMInst *pctmi; + SCPerfClubTMInst *pctmi; pthread_mutex_t pctmi_lock; -} PerfOPIfaceContext; - -void PerfInitCounterApi(void); - -void PerfInitOPCtx(void); - -void PerfSpawnThreads(void); - -void * PerfMgmtThread(void *); - -void * PerfWakeupThread(void *); - -uint16_t PerfTVRegisterCounter(char *, struct ThreadVars_ *, int, char *); - -uint16_t PerfTVRegisterAvgCounter(char *, struct ThreadVars_ *, int, char *); - -uint16_t PerfTVRegisterMaxCounter(char *, struct ThreadVars_ *, int, char *); - -uint16_t PerfTVRegisterIntervalCounter(char *, struct ThreadVars_ *, int, char *); - -uint16_t PerfRegisterCounter(char *, char *, int, char *, PerfContext *); - -uint16_t PerfRegisterAvgCounter(char *, char *, int, char *, PerfContext *); - -uint16_t PerfRegisterMaxCounter(char *, char *, int, char *, PerfContext *); - -uint16_t PerfRegisterIntervalCounter(char *, char *, int, char *, PerfContext *); - -int PerfCounterDisplay(uint16_t, PerfContext *, int); - -inline void PerfCounterIncr(uint16_t, PerfCounterArray *); - -inline void PerfCounterAddUI64(uint16_t, PerfCounterArray *, uint64_t); - -inline void PerfCounterAddDouble(uint16_t, PerfCounterArray *, double); - -inline void PerfCounterSetUI64(uint16_t, PerfCounterArray *, uint64_t); - -inline void PerfCounterSetDouble(uint16_t, PerfCounterArray *, double); - -int PerfAddToClubbedTMTable(char *, PerfContext *); - -PerfCounterArray * PerfGetCounterArrayRange(uint16_t, uint16_t, - PerfContext *); - -PerfCounterArray * PerfGetAllCountersArray(PerfContext *); - - -int PerfUpdateCounter(char *, char *, uint64_t, void *, PerfContext *); - -int PerfUpdateCounterArray(PerfCounterArray *, PerfContext *, int); - -void PerfOutputCounters(void); - -int PerfOutputCounterFileIface(void); - -void PerfReleaseResources(void); - -void PerfReleaseOPCtx(void); - -void PerfReleasePerfCounterS(PerfCounter *); - -void PerfReleaseCounter(PerfCounter *); - -void PerfReleasePCA(PerfCounterArray *); - -void PerfRegisterTests(void); +} SCPerfOPIfaceContext; + + +/* the initialization functions */ +void SCPerfInitCounterApi(void); +void SCPerfSpawnThreads(void); + +/* the ThreadVars counter registration functions */ +uint16_t SCPerfTVRegisterCounter(char *, struct ThreadVars_ *, int, char *); +uint16_t SCPerfTVRegisterAvgCounter(char *, struct ThreadVars_ *, int, char *); +uint16_t SCPerfTVRegisterMaxCounter(char *, struct ThreadVars_ *, int, char *); +uint16_t SCPerfTVRegisterIntervalCounter(char *, struct ThreadVars_ *, int, + char *, char *); + +/* the non-ThreadVars counter registration functions */ +uint16_t SCPerfRegisterCounter(char *, char *, int, char *, SCPerfContext *); +uint16_t SCPerfRegisterAvgCounter(char *, char *, int, char *, SCPerfContext *); +uint16_t SCPerfRegisterMaxCounter(char *, char *, int, char *, SCPerfContext *); +uint16_t SCPerfRegisterIntervalCounter(char *, char *, int, char *, + SCPerfContext *, char *); + +/* utility functions */ +int SCPerfAddToClubbedTMTable(char *, SCPerfContext *); +SCPerfCounterArray *SCPerfGetCounterArrayRange(uint16_t, uint16_t, SCPerfContext *); +SCPerfCounterArray * SCPerfGetAllCountersArray(SCPerfContext *); +int SCPerfCounterDisplay(uint16_t, SCPerfContext *, int); + +/* functions used to update local counter values */ +inline void SCPerfCounterIncr(uint16_t, SCPerfCounterArray *); +inline void SCPerfCounterAddUI64(uint16_t, SCPerfCounterArray *, uint64_t); +inline void SCPerfCounterAddDouble(uint16_t, SCPerfCounterArray *, double); +inline void SCPerfCounterSetUI64(uint16_t, SCPerfCounterArray *, uint64_t); +inline void SCPerfCounterSetDouble(uint16_t, SCPerfCounterArray *, double); + +int SCPerfUpdateCounterArray(SCPerfCounterArray *, SCPerfContext *, int); + +void SCPerfOutputCounters(void); + +/* functions used to free the resources alloted by the Perf counter API */ +void SCPerfReleaseResources(void); +void SCPerfReleaseSCPerfCounterS(SCPerfCounter *); +void SCPerfReleasePCA(SCPerfCounterArray *); + +void SCPerfRegisterTests(void); #endif /* __COUNTERS_H__ */ diff --git a/src/decode-ethernet.c b/src/decode-ethernet.c index 04381503f6..9e767bafa9 100644 --- a/src/decode-ethernet.c +++ b/src/decode-ethernet.c @@ -10,7 +10,7 @@ void DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_eth, tv->pca); + SCPerfCounterIncr(dtv->counter_eth, tv->sc_perf_pca); if (len < ETHERNET_HEADER_LEN) { DECODER_SET_EVENT(p,ETHERNET_PKT_TOO_SMALL); diff --git a/src/decode-gre.c b/src/decode-gre.c index 82b68c76b9..b4e81af8ad 100644 --- a/src/decode-gre.c +++ b/src/decode-gre.c @@ -21,7 +21,7 @@ void DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u uint16_t header_len = GRE_HDR_LEN; GRESreHdr *gsre = NULL; - PerfCounterIncr(dtv->counter_gre, tv->pca); + SCPerfCounterIncr(dtv->counter_gre, tv->sc_perf_pca); if(len < GRE_HDR_LEN) { DECODER_SET_EVENT(p,GRE_PKT_TOO_SMALL); diff --git a/src/decode-icmpv4.c b/src/decode-icmpv4.c index 093a63cb29..4130a710c3 100644 --- a/src/decode-icmpv4.c +++ b/src/decode-icmpv4.c @@ -157,7 +157,7 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) */ void DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_icmpv4, tv->pca); + SCPerfCounterIncr(dtv->counter_icmpv4, tv->sc_perf_pca); if (len < ICMPV4_HEADER_LEN) { DECODER_SET_EVENT(p,ICMPV4_PKT_TOO_SMALL); diff --git a/src/decode-icmpv6.c b/src/decode-icmpv6.c index 8ee0908703..2726f4be8b 100644 --- a/src/decode-icmpv6.c +++ b/src/decode-icmpv6.c @@ -202,7 +202,7 @@ void DecodePartialIPV6(Packet *p, uint8_t *partial_packet, uint16_t len ) void DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_icmpv6, tv->pca); + SCPerfCounterIncr(dtv->counter_icmpv6, tv->sc_perf_pca); if (len < ICMPV6_HEADER_LEN) { SCLogDebug("ICMPV6_PKT_TOO_SMALL"); diff --git a/src/decode-ipv4.c b/src/decode-ipv4.c index b14d7f2b05..cd5b5f8058 100644 --- a/src/decode-ipv4.c +++ b/src/decode-ipv4.c @@ -534,7 +534,7 @@ void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, { int ret; - PerfCounterIncr(dtv->counter_ipv4, tv->pca); + SCPerfCounterIncr(dtv->counter_ipv4, tv->sc_perf_pca); /* reset the decoder cache flags */ IPV4_CACHE_INIT(p); diff --git a/src/decode-ipv6.c b/src/decode-ipv6.c index 4da7187891..9e57dab909 100644 --- a/src/decode-ipv6.c +++ b/src/decode-ipv6.c @@ -365,7 +365,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, { int ret; - PerfCounterIncr(dtv->counter_ipv6, tv->pca); + SCPerfCounterIncr(dtv->counter_ipv6, tv->sc_perf_pca); IPV6_CACHE_INIT(p); diff --git a/src/decode-ppp.c b/src/decode-ppp.c index 9de47e24eb..b645eccbc2 100644 --- a/src/decode-ppp.c +++ b/src/decode-ppp.c @@ -13,7 +13,7 @@ void DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_ppp, tv->pca); + SCPerfCounterIncr(dtv->counter_ppp, tv->sc_perf_pca); if(len < PPP_HEADER_LEN) { DECODER_SET_EVENT(p,PPP_PKT_TOO_SMALL); diff --git a/src/decode-pppoe.c b/src/decode-pppoe.c index d212f1a1e1..dd05f6ccb5 100644 --- a/src/decode-pppoe.c +++ b/src/decode-pppoe.c @@ -22,7 +22,7 @@ */ void DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_pppoe, tv->pca); + SCPerfCounterIncr(dtv->counter_pppoe, tv->sc_perf_pca); if (len < PPPOE_DISCOVERY_HEADER_MIN_LEN) { DECODER_SET_EVENT(p, PPPOE_PKT_TOO_SMALL); @@ -94,7 +94,7 @@ void DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint */ void DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_pppoe, tv->pca); + SCPerfCounterIncr(dtv->counter_pppoe, tv->sc_perf_pca); if (len < PPPOE_SESSION_HEADER_LEN) { DECODER_SET_EVENT(p, PPPOE_PKT_TOO_SMALL); diff --git a/src/decode-sll.c b/src/decode-sll.c index 80476373dd..4d23011cef 100644 --- a/src/decode-sll.c +++ b/src/decode-sll.c @@ -7,7 +7,7 @@ void DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_sll, tv->pca); + SCPerfCounterIncr(dtv->counter_sll, tv->sc_perf_pca); if (len < SLL_HEADER_LEN) { DECODER_SET_EVENT(p,SLL_PKT_TOO_SMALL); diff --git a/src/decode-tcp.c b/src/decode-tcp.c index accdd62882..5f6c3b0e33 100644 --- a/src/decode-tcp.c +++ b/src/decode-tcp.c @@ -259,7 +259,7 @@ static int DecodeTCPPacket(ThreadVars *tv, Packet *p, uint8_t *pkt, uint16_t len void DecodeTCP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_tcp, tv->pca); + SCPerfCounterIncr(dtv->counter_tcp, tv->sc_perf_pca); if (DecodeTCPPacket(tv, p,pkt,len) < 0) { p->tcph = NULL; diff --git a/src/decode-udp.c b/src/decode-udp.c index 9b9fded523..8969fb8bf8 100644 --- a/src/decode-udp.c +++ b/src/decode-udp.c @@ -161,7 +161,7 @@ static int DecodeUDPPacket(ThreadVars *t, Packet *p, uint8_t *pkt, uint16_t len) void DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { - PerfCounterIncr(dtv->counter_udp, tv->pca); + SCPerfCounterIncr(dtv->counter_udp, tv->sc_perf_pca); if (DecodeUDPPacket(tv, p,pkt,len) < 0) { p->udph = NULL; diff --git a/src/detect-engine.c b/src/detect-engine.c index 545ab1ec6c..222a01ef24 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -120,9 +120,10 @@ TmEcode DetectEngineThreadCtxInit(ThreadVars *tv, void *initdata, void **data) { DetectEngineIPOnlyThreadInit(de_ctx,&det_ctx->io_ctx); /** alert counter setup */ - det_ctx->counter_alerts = PerfTVRegisterCounter("detect.alert", tv, TYPE_UINT64, "NULL"); - tv->pca = PerfGetAllCountersArray(&tv->pctx); - PerfAddToClubbedTMTable(tv->name, &tv->pctx); + det_ctx->counter_alerts = SCPerfTVRegisterCounter("detect.alert", tv, + SC_PERF_TYPE_UINT64, "NULL"); + tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); + SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); *data = (void *)det_ctx; //printf("DetectEngineThreadCtxInit: data %p det_ctx %p\n", *data, det_ctx); diff --git a/src/eidps.c b/src/eidps.c index 8b8898fc14..23b12f535d 100644 --- a/src/eidps.c +++ b/src/eidps.c @@ -393,7 +393,7 @@ int main(int argc, char **argv) CIDRInit(); SigParsePrepare(); //PatternMatchPrepare(mpm_ctx, MPM_B2G); - PerfInitCounterApi(); + SCPerfInitCounterApi(); /** \todo we need an api for these */ AppLayerDetectProtoThreadInit(); @@ -446,7 +446,7 @@ int main(int argc, char **argv) ByteRegisterTests(); MpmRegisterTests(); FlowBitRegisterTests(); - PerfRegisterTests(); + SCPerfRegisterTests(); DecodePPPRegisterTests(); HTTPParserRegisterTests(); TLSParserRegisterTests(); @@ -567,7 +567,7 @@ int main(int argc, char **argv) //AppLayerDetectProtoThreadSpawn(); /* Spawn the perf counter threads. Let these be the last one spawned */ - PerfSpawnThreads(); + SCPerfSpawnThreads(); /* Check if the alloted queues have at least 1 reader and writer */ TmValidateQueueState(); @@ -622,7 +622,7 @@ int main(int argc, char **argv) SCLogInfo("time elapsed %" PRIuMAX "s", (uintmax_t)(end_time.tv_sec - start_time.tv_sec)); TmThreadKillThreads(); - PerfReleaseResources(); + SCPerfReleaseResources(); break; } diff --git a/src/flow.c b/src/flow.c index 318e7e731f..a1ab966439 100644 --- a/src/flow.c +++ b/src/flow.c @@ -576,7 +576,7 @@ void *FlowManagerThread(void *td) } if (TmThreadsCheckFlag(th_v, THV_KILL)) { - PerfUpdateCounterArray(th_v->pca, &th_v->pctx, 0); + SCPerfUpdateCounterArray(th_v->sc_perf_pca, &th_v->sc_perf_pctx, 0); break; } diff --git a/src/source-nfq.c b/src/source-nfq.c index 90e895ff65..d8fb8077ee 100644 --- a/src/source-nfq.c +++ b/src/source-nfq.c @@ -461,10 +461,10 @@ TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) printf("DecodeNFQ\n"); #endif - PerfCounterIncr(dtv->counter_pkts, tv->pca); - PerfCounterAddUI64(dtv->counter_bytes, tv->pca, p->pktlen); - PerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->pca, p->pktlen); - PerfCounterSetUI64(dtv->counter_max_pkt_size, tv->pca, p->pktlen); + SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca); + SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, p->pktlen); + SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, p->pktlen); + SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, p->pktlen); if (IPV4_GET_RAW_VER(ip4h) == 4) { #ifdef DEBUG @@ -496,27 +496,40 @@ TmEcode DecodeNFQThreadInit(ThreadVars *tv, void *initdata, void **data) memset(dtv, 0, sizeof(DecodeThreadVars)); /* register counters */ - dtv->counter_pkts = PerfTVRegisterCounter("decoder.pkts", tv, TYPE_UINT64, "NULL"); - dtv->counter_bytes = PerfTVRegisterCounter("decoder.bytes", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv4 = PerfTVRegisterCounter("decoder.ipv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv6 = PerfTVRegisterCounter("decoder.ipv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_eth = PerfTVRegisterCounter("decoder.ethernet", tv, TYPE_UINT64, "NULL"); - dtv->counter_sll = PerfTVRegisterCounter("decoder.sll", tv, TYPE_UINT64, "NULL"); - dtv->counter_tcp = PerfTVRegisterCounter("decoder.tcp", tv, TYPE_UINT64, "NULL"); - dtv->counter_udp = PerfTVRegisterCounter("decoder.udp", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv4 = PerfTVRegisterCounter("decoder.icmpv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv6 = PerfTVRegisterCounter("decoder.icmpv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_ppp = PerfTVRegisterCounter("decoder.ppp", tv, TYPE_UINT64, "NULL"); - dtv->counter_pppoe = PerfTVRegisterCounter("decoder.pppoe", tv, TYPE_UINT64, "NULL"); - dtv->counter_gre = PerfTVRegisterCounter("decoder.gre", tv, TYPE_UINT64, "NULL"); - dtv->counter_avg_pkt_size = PerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, - TYPE_DOUBLE, "NULL"); - dtv->counter_max_pkt_size = PerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, - TYPE_UINT64, "NULL"); - - tv->pca = PerfGetAllCountersArray(&tv->pctx); - - PerfAddToClubbedTMTable(tv->name, &tv->pctx); + dtv->counter_pkts = SCPerfTVRegisterCounter("decoder.pkts", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_bytes = SCPerfTVRegisterCounter("decoder.bytes", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv4 = SCPerfTVRegisterCounter("decoder.ipv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv6 = SCPerfTVRegisterCounter("decoder.ipv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_eth = SCPerfTVRegisterCounter("decoder.ethernet", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_sll = SCPerfTVRegisterCounter("decoder.sll", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_tcp = SCPerfTVRegisterCounter("decoder.tcp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_udp = SCPerfTVRegisterCounter("decoder.udp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv4 = SCPerfTVRegisterCounter("decoder.icmpv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv6 = SCPerfTVRegisterCounter("decoder.icmpv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ppp = SCPerfTVRegisterCounter("decoder.ppp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_pppoe = SCPerfTVRegisterCounter("decoder.pppoe", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_gre = SCPerfTVRegisterCounter("decoder.gre", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_avg_pkt_size = SCPerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, + SC_PERF_TYPE_DOUBLE, "NULL"); + dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, + SC_PERF_TYPE_UINT64, "NULL"); + + tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); + + SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); *data = (void *)dtv; diff --git a/src/source-pcap-file.c b/src/source-pcap-file.c index 4c9f62ba49..99956abc60 100644 --- a/src/source-pcap-file.c +++ b/src/source-pcap-file.c @@ -168,10 +168,10 @@ TmEcode DecodePcapFile(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) DecodeThreadVars *dtv = (DecodeThreadVars *)data; /* update counters */ - PerfCounterIncr(dtv->counter_pkts, tv->pca); - PerfCounterAddUI64(dtv->counter_bytes, tv->pca, p->pktlen); - PerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->pca, p->pktlen); - PerfCounterSetUI64(dtv->counter_max_pkt_size, tv->pca, p->pktlen); + SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca); + SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, p->pktlen); + SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, p->pktlen); + SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, p->pktlen); /* call the decoder */ pcap_g.Decoder(tv, dtv, p, p->pkt, p->pktlen, pq); @@ -190,28 +190,42 @@ TmEcode DecodePcapFileThreadInit(ThreadVars *tv, void *initdata, void **data) memset(dtv, 0, sizeof(DecodeThreadVars)); /* register counters */ - dtv->counter_pkts = PerfTVRegisterCounter("decoder.pkts", tv, TYPE_UINT64, "NULL"); - dtv->counter_bytes = PerfTVRegisterCounter("decoder.bytes", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv4 = PerfTVRegisterCounter("decoder.ipv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv6 = PerfTVRegisterCounter("decoder.ipv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_eth = PerfTVRegisterCounter("decoder.ethernet", tv, TYPE_UINT64, "NULL"); - dtv->counter_sll = PerfTVRegisterCounter("decoder.sll", tv, TYPE_UINT64, "NULL"); - dtv->counter_tcp = PerfTVRegisterCounter("decoder.tcp", tv, TYPE_UINT64, "NULL"); - dtv->counter_udp = PerfTVRegisterCounter("decoder.udp", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv4 = PerfTVRegisterCounter("decoder.icmpv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv6 = PerfTVRegisterCounter("decoder.icmpv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_ppp = PerfTVRegisterCounter("decoder.ppp", tv, TYPE_UINT64, "NULL"); - dtv->counter_pppoe = PerfTVRegisterCounter("decoder.pppoe", tv, TYPE_UINT64, "NULL"); - dtv->counter_gre = PerfTVRegisterCounter("decoder.gre", tv, TYPE_UINT64, "NULL"); - dtv->counter_avg_pkt_size = PerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, - TYPE_DOUBLE, "NULL"); - dtv->counter_max_pkt_size = PerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, - TYPE_UINT64, "NULL"); - - tv->pca = PerfGetAllCountersArray(&tv->pctx); - PerfAddToClubbedTMTable(tv->name, &tv->pctx); + dtv->counter_pkts = SCPerfTVRegisterCounter("decoder.pkts", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_bytes = SCPerfTVRegisterCounter("decoder.bytes", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv4 = SCPerfTVRegisterCounter("decoder.ipv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv6 = SCPerfTVRegisterCounter("decoder.ipv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_eth = SCPerfTVRegisterCounter("decoder.ethernet", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_sll = SCPerfTVRegisterCounter("decoder.sll", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_tcp = SCPerfTVRegisterCounter("decoder.tcp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_udp = SCPerfTVRegisterCounter("decoder.udp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv4 = SCPerfTVRegisterCounter("decoder.icmpv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv6 = SCPerfTVRegisterCounter("decoder.icmpv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ppp = SCPerfTVRegisterCounter("decoder.ppp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_pppoe = SCPerfTVRegisterCounter("decoder.pppoe", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_gre = SCPerfTVRegisterCounter("decoder.gre", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_avg_pkt_size = SCPerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, + SC_PERF_TYPE_DOUBLE, "NULL"); + dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, + SC_PERF_TYPE_UINT64, "NULL"); + + tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); + SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); *data = (void *)dtv; + return TM_ECODE_OK; } diff --git a/src/source-pcap.c b/src/source-pcap.c index 22e5437746..19f62936bd 100644 --- a/src/source-pcap.c +++ b/src/source-pcap.c @@ -289,10 +289,10 @@ TmEcode DecodePcap(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) DecodeThreadVars *dtv = (DecodeThreadVars *)data; /* update counters */ - PerfCounterIncr(dtv->counter_pkts, tv->pca); - PerfCounterAddUI64(dtv->counter_bytes, tv->pca, p->pktlen); - PerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->pca, p->pktlen); - PerfCounterSetUI64(dtv->counter_max_pkt_size, tv->pca, p->pktlen); + SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca); + SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, p->pktlen); + SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, p->pktlen); + SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, p->pktlen); /* call the decoder */ switch(p->datalink) { @@ -324,28 +324,42 @@ TmEcode DecodePcapThreadInit(ThreadVars *tv, void *initdata, void **data) memset(dtv, 0, sizeof(DecodeThreadVars)); /* register counters */ - dtv->counter_pkts = PerfTVRegisterCounter("decoder.pkts", tv, TYPE_UINT64, "NULL"); - dtv->counter_bytes = PerfTVRegisterCounter("decoder.bytes", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv4 = PerfTVRegisterCounter("decoder.ipv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv6 = PerfTVRegisterCounter("decoder.ipv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_eth = PerfTVRegisterCounter("decoder.ethernet", tv, TYPE_UINT64, "NULL"); - dtv->counter_sll = PerfTVRegisterCounter("decoder.sll", tv, TYPE_UINT64, "NULL"); - dtv->counter_tcp = PerfTVRegisterCounter("decoder.tcp", tv, TYPE_UINT64, "NULL"); - dtv->counter_udp = PerfTVRegisterCounter("decoder.udp", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv4 = PerfTVRegisterCounter("decoder.icmpv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv6 = PerfTVRegisterCounter("decoder.icmpv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_ppp = PerfTVRegisterCounter("decoder.ppp", tv, TYPE_UINT64, "NULL"); - dtv->counter_pppoe = PerfTVRegisterCounter("decoder.pppoe", tv, TYPE_UINT64, "NULL"); - dtv->counter_gre = PerfTVRegisterCounter("decoder.gre", tv, TYPE_UINT64, "NULL"); - dtv->counter_avg_pkt_size = PerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, - TYPE_DOUBLE, "NULL"); - dtv->counter_max_pkt_size = PerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, - TYPE_UINT64, "NULL"); - - tv->pca = PerfGetAllCountersArray(&tv->pctx); - PerfAddToClubbedTMTable(tv->name, &tv->pctx); + dtv->counter_pkts = SCPerfTVRegisterCounter("decoder.pkts", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_bytes = SCPerfTVRegisterCounter("decoder.bytes", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv4 = SCPerfTVRegisterCounter("decoder.ipv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv6 = SCPerfTVRegisterCounter("decoder.ipv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_eth = SCPerfTVRegisterCounter("decoder.ethernet", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_sll = SCPerfTVRegisterCounter("decoder.sll", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_tcp = SCPerfTVRegisterCounter("decoder.tcp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_udp = SCPerfTVRegisterCounter("decoder.udp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv4 = SCPerfTVRegisterCounter("decoder.icmpv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv6 = SCPerfTVRegisterCounter("decoder.icmpv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ppp = SCPerfTVRegisterCounter("decoder.ppp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_pppoe = SCPerfTVRegisterCounter("decoder.pppoe", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_gre = SCPerfTVRegisterCounter("decoder.gre", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_avg_pkt_size = SCPerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, + SC_PERF_TYPE_DOUBLE, "NULL"); + dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, + SC_PERF_TYPE_UINT64, "NULL"); + + tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); + SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); *data = (void *)dtv; + return TM_ECODE_OK; } diff --git a/src/source-pfring.c b/src/source-pfring.c index 8dcaa7310b..177e9e45fc 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -285,10 +285,10 @@ TmEcode DecodePfring(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq) DecodeThreadVars *dtv = (DecodeThreadVars *)data; /* update counters */ - PerfCounterIncr(dtv->counter_pkts, tv->pca); - PerfCounterAddUI64(dtv->counter_bytes, tv->pca, p->pktlen); - PerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->pca, p->pktlen); - PerfCounterSetUI64(dtv->counter_max_pkt_size, tv->pca, p->pktlen); + SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca); + SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, p->pktlen); + SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, p->pktlen); + SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, p->pktlen); DecodeEthernet(tv, dtv, p,p->pkt, p->pktlen, pq); @@ -315,28 +315,42 @@ TmEcode DecodePfringThreadInit(ThreadVars *tv, void *initdata, void **data) memset(dtv, 0, sizeof(DecodeThreadVars)); /* register counters */ - dtv->counter_pkts = PerfTVRegisterCounter("decoder.pkts", tv, TYPE_UINT64, "NULL"); - dtv->counter_bytes = PerfTVRegisterCounter("decoder.bytes", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv4 = PerfTVRegisterCounter("decoder.ipv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_ipv6 = PerfTVRegisterCounter("decoder.ipv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_eth = PerfTVRegisterCounter("decoder.ethernet", tv, TYPE_UINT64, "NULL"); - dtv->counter_sll = PerfTVRegisterCounter("decoder.sll", tv, TYPE_UINT64, "NULL"); - dtv->counter_tcp = PerfTVRegisterCounter("decoder.tcp", tv, TYPE_UINT64, "NULL"); - dtv->counter_udp = PerfTVRegisterCounter("decoder.udp", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv4 = PerfTVRegisterCounter("decoder.icmpv4", tv, TYPE_UINT64, "NULL"); - dtv->counter_icmpv6 = PerfTVRegisterCounter("decoder.icmpv6", tv, TYPE_UINT64, "NULL"); - dtv->counter_ppp = PerfTVRegisterCounter("decoder.ppp", tv, TYPE_UINT64, "NULL"); - dtv->counter_pppoe = PerfTVRegisterCounter("decoder.pppoe", tv, TYPE_UINT64, "NULL"); - dtv->counter_gre = PerfTVRegisterCounter("decoder.gre", tv, TYPE_UINT64, "NULL"); - dtv->counter_avg_pkt_size = PerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, - TYPE_DOUBLE, "NULL"); - dtv->counter_max_pkt_size = PerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, - TYPE_UINT64, "NULL"); - - tv->pca = PerfGetAllCountersArray(&tv->pctx); - PerfAddToClubbedTMTable(tv->name, &tv->pctx); + dtv->counter_pkts = SCPerfTVRegisterCounter("decoder.pkts", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_bytes = SCPerfTVRegisterCounter("decoder.bytes", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv4 = SCPerfTVRegisterCounter("decoder.ipv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ipv6 = SCPerfTVRegisterCounter("decoder.ipv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_eth = SCPerfTVRegisterCounter("decoder.ethernet", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_sll = SCPerfTVRegisterCounter("decoder.sll", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_tcp = SCPerfTVRegisterCounter("decoder.tcp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_udp = SCPerfTVRegisterCounter("decoder.udp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv4 = SCPerfTVRegisterCounter("decoder.icmpv4", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_icmpv6 = SCPerfTVRegisterCounter("decoder.icmpv6", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_ppp = SCPerfTVRegisterCounter("decoder.ppp", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_pppoe = SCPerfTVRegisterCounter("decoder.pppoe", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_gre = SCPerfTVRegisterCounter("decoder.gre", tv, + SC_PERF_TYPE_UINT64, "NULL"); + dtv->counter_avg_pkt_size = SCPerfTVRegisterAvgCounter("decoder.avg_pkt_size", tv, + SC_PERF_TYPE_DOUBLE, "NULL"); + dtv->counter_max_pkt_size = SCPerfTVRegisterMaxCounter("decoder.max_pkt_size", tv, + SC_PERF_TYPE_UINT64, "NULL"); + + tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); + SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); *data = (void *)dtv; + return TM_ECODE_OK; } #endif /* HAVE_PFRING */ diff --git a/src/stream-tcp.c b/src/stream-tcp.c index 65bfee0769..e9abcd4c0d 100644 --- a/src/stream-tcp.c +++ b/src/stream-tcp.c @@ -284,7 +284,7 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread * if (ssn == NULL) return -1; - PerfCounterIncr(stt->counter_tcp_sessions, tv->pca); + SCPerfCounterIncr(stt->counter_tcp_sessions, tv->sc_perf_pca); } /* set the state */ @@ -326,7 +326,7 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread * ssn = StreamTcpNewSession(p); if (ssn == NULL) return -1; - PerfCounterIncr(stt->counter_tcp_sessions, tv->pca); + SCPerfCounterIncr(stt->counter_tcp_sessions, tv->sc_perf_pca); } /* set the state */ StreamTcpPacketSetState(p, ssn, TCP_SYN_RECV); @@ -387,7 +387,7 @@ static int StreamTcpPacketStateNone(ThreadVars *tv, Packet *p, StreamTcpThread * ssn = StreamTcpNewSession(p); if (ssn == NULL) return -1; - PerfCounterIncr(stt->counter_tcp_sessions, tv->pca); + SCPerfCounterIncr(stt->counter_tcp_sessions, tv->sc_perf_pca); } /* set the state */ StreamTcpPacketSetState(p, ssn, TCP_ESTABLISHED); @@ -1495,9 +1495,10 @@ TmEcode StreamTcpThreadInit(ThreadVars *tv, void *initdata, void **data) *data = (void *)stt; - stt->counter_tcp_sessions = PerfTVRegisterCounter("tcp.sessions", tv, TYPE_UINT64, "NULL"); - tv->pca = PerfGetAllCountersArray(&tv->pctx); - PerfAddToClubbedTMTable(tv->name, &tv->pctx); + stt->counter_tcp_sessions = SCPerfTVRegisterCounter("tcp.sessions", tv, + SC_PERF_TYPE_UINT64, "NULL"); + tv->sc_perf_pca = SCPerfGetAllCountersArray(&tv->sc_perf_pctx); + SCPerfAddToClubbedTMTable(tv->name, &tv->sc_perf_pctx); /* init reassembly ctx */ stt->ra_ctx = StreamTcpReassembleInitThreadCtx(); diff --git a/src/threadvars.h b/src/threadvars.h index 8ab4b0f24e..e8acd279b6 100644 --- a/src/threadvars.h +++ b/src/threadvars.h @@ -57,8 +57,9 @@ typedef struct ThreadVars_ { char set_cpu_affinity; /** bool: 0 no, 1 yes */ int cpu_affinity; /** cpu or core number to set affinity to */ - PerfContext pctx; - PerfCounterArray *pca; + /* the perf counter context and the perf counter array */ + SCPerfContext sc_perf_pctx; + SCPerfCounterArray *sc_perf_pca; pthread_mutex_t *m; pthread_cond_t *cond; diff --git a/src/tm-threads.c b/src/tm-threads.c index 415302f126..56085047ac 100644 --- a/src/tm-threads.c +++ b/src/tm-threads.c @@ -135,7 +135,7 @@ void *TmThreadsSlot1NoIn(void *td) { tv->tmqh_out(tv, p); if (TmThreadsCheckFlag(tv, THV_KILL)) { - PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); + SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } @@ -193,7 +193,7 @@ void *TmThreadsSlot1NoOut(void *td) { } if (TmThreadsCheckFlag(tv, THV_KILL)) { - PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); + SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } @@ -252,7 +252,7 @@ void *TmThreadsSlot1NoInOut(void *td) { if (TmThreadsCheckFlag(tv, THV_KILL)) { //printf("%s: TmThreadsSlot1NoInOut: KILL is set\n", tv->name); - PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); + SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } @@ -330,7 +330,7 @@ void *TmThreadsSlot1(void *td) { if (TmThreadsCheckFlag(tv, THV_KILL)) { //printf("%s: TmThreadsSlot1: KILL is set\n", tv->name); - PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); + SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } @@ -443,7 +443,7 @@ void *TmThreadsSlotVar(void *td) { if (TmThreadsCheckFlag(tv, THV_KILL)) { //printf("%s: TmThreadsSlot1: KILL is set\n", tv->name); - PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); + SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); run = 0; } } diff --git a/src/tmqh-flow.c b/src/tmqh-flow.c index 3e5ddec3a1..bd595f0163 100644 --- a/src/tmqh-flow.c +++ b/src/tmqh-flow.c @@ -55,8 +55,8 @@ Packet *TmqhInputFlow(ThreadVars *tv) pthread_cond_wait(&q->cond_q, &q->mutex_q); } - if (tv->pctx.perf_flag == 1) - PerfUpdateCounterArray(tv->pca, &tv->pctx, 0); + if (tv->sc_perf_pctx.perf_flag == 1) + SCPerfUpdateCounterArray(tv->sc_perf_pca, &tv->sc_perf_pctx, 0); if (q->len > 0) { Packet *p = PacketDequeue(q); diff --git a/src/tmqh-simple.c b/src/tmqh-simple.c index c32f283916..c5ae40d356 100644 --- a/src/tmqh-simple.c +++ b/src/tmqh-simple.c @@ -26,8 +26,8 @@ Packet *TmqhInputSimple(ThreadVars *t) pthread_cond_wait(&q->cond_q, &q->mutex_q); } - if (t->pctx.perf_flag == 1) - PerfUpdateCounterArray(t->pca, &t->pctx, 0); + if (t->sc_perf_pctx.perf_flag == 1) + SCPerfUpdateCounterArray(t->sc_perf_pca, &t->sc_perf_pctx, 0); if (q->len > 0) { Packet *p = PacketDequeue(q); diff --git a/src/util-error.h b/src/util-error.h index 8c3ca0630a..cbc86d6945 100644 --- a/src/util-error.h +++ b/src/util-error.h @@ -23,6 +23,12 @@ typedef enum { SC_INVALID_IPV4_ADDR, SC_INVALID_IPV6_ADDR, SC_ERR_INVALID_SIGNATURE, + SC_ERR_OPENING_FILE, + SC_INITIALIZATION_ERROR, + SC_THREAD_SPAWN_FAILED, + SC_ERR_SYSCALL, + SC_INVALID_ARGUMENTS, + SC_ERR_THREAD_CREATE_ERROR, } SCError; const char *SCErrorToString(SCError);