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;
|
||
|
/**
|
||