Bug #50 ยป 0001-Fix-for-bug-50.-Make-timebased-counters-more-accura.patch
src/counters.c | ||
---|---|---|
pc->type_q->total_secs = ((pc->type_q->hours * 60 * 60) +
|
||
(pc->type_q->minutes * 60) + pc->type_q->seconds);
|
||
TimeGet(&pc->type_q->ts);
|
||
free(regex);
|
||
return 0;
|
||
... | ... | |
double d_temp = 0;
|
||
uint64_t ui64_temp = 0;
|
||
struct timeval curr_ts;
|
||
uint64_t u = 0;
|
||
pc = pcae->pc;
|
||
... | ... | |
*((uint64_t *)pc->value->cvalue) = ui64_temp;
|
||
} else if (pc->type_q->type & SC_PERF_TYPE_Q_TIMEBASED) {
|
||
/* we have a timebased counter. Awesome. Time for some more processing */
|
||
TimeGet(&curr_ts);
|
||
pc->type_q->tbc_secs += ((curr_ts.tv_sec + curr_ts.tv_usec / 1000000.0) -
|
||
(pcae->ts.tv_sec + pcae->ts.tv_usec / 1000000.0));
|
||
/* special treatment for timebased counters. We add instead of
|
||
* copying to the global counters. The job of resetting the
|
||
* global counters is done by the output function */
|
||
*((uint64_t *)pc->value->cvalue) += ui64_temp;
|
||
pcae->ui64_cnt = 0;
|
||
/* reset it to the current time */
|
||
TimeGet(&pcae->ts);
|
||
} else {
|
||
*((uint64_t *)pc->value->cvalue) = ui64_temp;
|
||
}
|
||
... | ... | |
*((double *)pc->value->cvalue) = d_temp;
|
||
} else if (pc->type_q->type & SC_PERF_TYPE_Q_TIMEBASED) {
|
||
/* we have a timebased counter. Awesome. Time for some more processing */
|
||
TimeGet(&curr_ts);
|
||
pc->type_q->tbc_secs += ((curr_ts.tv_sec + curr_ts.tv_usec / 1000000.0) -
|
||
(pcae->ts.tv_sec + pcae->ts.tv_usec / 1000000.0));
|
||
/* special treatment for timebased counters. We add instead of
|
||
* copying to the global counters. The job of resetting the
|
||
* global counters is done by the output function */
|
||
*((double *)pc->value->cvalue) += d_temp;
|
||
pcae->d_cnt = 0;
|
||
/* reset it to the current time */
|
||
TimeGet(&pcae->ts);
|
||
} else {
|
||
*((double *)pc->value->cvalue) = d_temp;
|
||
}
|
||
... | ... | |
*/
|
||
static void SCPerfOutputCalculateCounterValue(SCPerfCounter *pc, void *cvalue_op)
|
||
{
|
||
struct timeval curr_ts;
|
||
int elapsed_secs = 0;
|
||
double divisor = 0;
|
||
switch (pc->value->type) {
|
||
... | ... | |
if ( !(pc->type_q->type & SC_PERF_TYPE_Q_TIMEBASED))
|
||
return;
|
||
/* we have a timebased counter. Awesome. Time for some more processing */
|
||
TimeGet(&curr_ts);
|
||
elapsed_secs = ((curr_ts.tv_sec + curr_ts.tv_usec / 1000000.0) -
|
||
(pc->type_q->ts.tv_sec + pc->type_q->ts.tv_usec / 1000000.0));
|
||
//if (pc->type_q->tbc_secs < pc->type_q->total_secs)
|
||
// return;
|
||
if (elapsed_secs < pc->type_q->total_secs)
|
||
return;
|
||
divisor = elapsed_secs/pc->type_q->total_secs;
|
||
divisor += ((double)(elapsed_secs % pc->type_q->total_secs)/
|
||
divisor = pc->type_q->tbc_secs/pc->type_q->total_secs;
|
||
divisor += ((double)(pc->type_q->tbc_secs % pc->type_q->total_secs)/
|
||
pc->type_q->total_secs);
|
||
switch (pc->value->type) {
|
||
... | ... | |
break;
|
||
}
|
||
/* reset the timestamp to the current time */
|
||
TimeGet(&pc->type_q->ts);
|
||
pc->type_q->tbc_secs = 0;
|
||
/* reset the local counter back to 0 */
|
||
memset(pc->value->cvalue, 0, pc->value->size);
|
||
... | ... | |
while ((pc != NULL) && (pc->id <= e_id)) {
|
||
pca->head[i].pc = pc;
|
||
pca->head[i].id = pc->id;
|
||
if (pc->type_q->type & SC_PERF_TYPE_Q_TIMEBASED)
|
||
TimeGet(&pca->head[i].ts);
|
||
pc = pc->next;
|
||
i++;
|
||
}
|
||
... | ... | |
SCPerfCounterAddDouble(id1, pca, 5);
|
||
SCPerfCounterAddDouble(id1, pca, 6);
|
||
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
|
||
/* forward the time 6 seconds */
|
||
TimeSetIncrementTime(6);
|
||
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
|
||
SCPerfOutputCalculateCounterValue(tv.sc_perf_pctx.head, &d_temp);
|
||
result &= (d_temp > 10 && d_temp < 11);
|
||
... | ... | |
SCPerfCounterAddDouble(id1, pca, 5);
|
||
SCPerfCounterAddDouble(id1, pca, 6);
|
||
/* forward the time 3 seconds */
|
||
TimeSetIncrementTime(3);
|
||
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
|
||
SCPerfOutputCalculateCounterValue(tv.sc_perf_pctx.head, &d_temp);
|
||
return (d_temp == 1050.0);
|
||
}
|
||
static int SCPerfTestIntervalQual18()
|
||
{
|
||
ThreadVars tv;
|
||
SCPerfCounterArray *pca = NULL;
|
||
double d_temp = 0;
|
||
int result = 1;
|
||
uint16_t id1;
|
||
memset(&tv, 0, sizeof(ThreadVars));
|
||
id1 = SCPerfRegisterIntervalCounter("t1", "c1", SC_PERF_TYPE_DOUBLE, NULL,
|
||
&tv.sc_perf_pctx, "3s");
|
||
pca = SCPerfGetAllCountersArray(&tv.sc_perf_pctx);
|
||
SCPerfCounterAddDouble(id1, pca, 1);
|
||
SCPerfCounterAddDouble(id1, pca, 2);
|
||
SCPerfCounterAddDouble(id1, pca, 3);
|
||
SCPerfCounterAddDouble(id1, pca, 4);
|
||
SCPerfCounterAddDouble(id1, pca, 5);
|
||
SCPerfCounterAddDouble(id1, pca, 6);
|
||
/* forward the time 3 seconds */
|
||
TimeSetIncrementTime(3);
|
||
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
|
||
SCPerfCounterAddDouble(id1, pca, 1);
|
||
SCPerfCounterAddDouble(id1, pca, 2);
|
||
SCPerfCounterAddDouble(id1, pca, 3);
|
||
/* forward the time 3 seconds */
|
||
TimeSetIncrementTime(3);
|
||
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
|
||
SCPerfCounterAddDouble(id1, pca, 3);
|
||
SCPerfCounterAddDouble(id1, pca, 3);
|
||
/* forward the time 3 seconds */
|
||
TimeSetIncrementTime(3);
|
||
SCPerfOutputCalculateCounterValue(tv.sc_perf_pctx.head, &d_temp);
|
||
result &= (d_temp == 13.5);
|
||
SCPerfCounterAddDouble(id1, pca, 1);
|
||
SCPerfCounterAddDouble(id1, pca, 2);
|
||
SCPerfCounterAddDouble(id1, pca, 3);
|
||
/* forward the time 3 seconds */
|
||
TimeSetIncrementTime(3);
|
||
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
|
||
SCPerfCounterAddDouble(id1, pca, 1);
|
||
SCPerfCounterAddDouble(id1, pca, 2);
|
||
SCPerfCounterAddDouble(id1, pca, 3);
|
||
/* forward the time 1 second */
|
||
TimeSetIncrementTime(1);
|
||
SCPerfOutputCalculateCounterValue(tv.sc_perf_pctx.head, &d_temp);
|
||
return (d_temp == 21);
|
||
result &= (d_temp == 6);
|
||
SCPerfCounterAddDouble(id1, pca, 2);
|
||
/* forward the time 1 second */
|
||
TimeSetIncrementTime(1);
|
||
SCPerfUpdateCounterArray(pca, &tv.sc_perf_pctx, 0);
|
||
SCPerfOutputCalculateCounterValue(tv.sc_perf_pctx.head, &d_temp);
|
||
result &= (d_temp == 12.0);
|
||
return result;
|
||
}
|
||
void SCPerfRegisterTests()
|
||
... | ... | |
UtRegisterTest("SCPerfTestIntervalQual15", SCPerfTestIntervalQual15, 1);
|
||
UtRegisterTest("SCPerfTestIntervalQual16", SCPerfTestIntervalQual16, 1);
|
||
UtRegisterTest("SCPerfTestIntervalQual17", SCPerfTestIntervalQual17, 1);
|
||
UtRegisterTest("SCPerfTestIntervalQual18", SCPerfTestIntervalQual18, 1);
|
||
return;
|
||
}
|
src/counters.h | ||
---|---|---|
int total_secs;
|
||
/* timestamp to indicate the time, when the counter was last reset */
|
||
struct timeval ts;
|
||
/* the time interval that corresponds to the value stored for this counter.
|
||
* Used for time_based_counters(tbc). This represents the time period over
|
||
* which the value in this counter was accumulated. */
|
||
uint8_t tbc_secs;
|
||
} SCPerfCounterTypeQ;
|
||
/**
|
||
... | ... | |
/* indicates the times syncs has overflowed */
|
||
uint64_t wrapped_syncs;
|
||
/* timestamp to indicate the time, when the counter was last used to update
|
||
* the global counter. It is used for timebased counter calculations */
|
||
struct timeval ts;
|
||
} SCPCAElem;
|
||
/**
|