42
42
#include <limits.h>
43
43
#include <math.h>
44
44
#include <signal.h>
45
+ #include <time.h>
45
46
#include <sys/time.h>
46
47
#ifdef HAVE_SYS_SELECT_H
47
48
#include <sys/select.h>
@@ -227,7 +228,7 @@ typedef struct SimpleStats
227
228
*/
228
229
typedef struct StatsData
229
230
{
230
- long start_time ; /* interval start time, for aggregates */
231
+ time_t start_time ; /* interval start time, for aggregates */
231
232
int64 cnt ; /* number of transactions */
232
233
int64 skipped ; /* number of transactions skipped under --rate
233
234
* and --latency-limit */
@@ -449,7 +450,7 @@ static const BuiltinScript builtin_script[] =
449
450
static void setIntValue (PgBenchValue * pv , int64 ival );
450
451
static void setDoubleValue (PgBenchValue * pv , double dval );
451
452
static bool evaluateExpr (TState * , CState * , PgBenchExpr * , PgBenchValue * );
452
- static void doLog (TState * thread , CState * st , instr_time * now ,
453
+ static void doLog (TState * thread , CState * st ,
453
454
StatsData * agg , bool skipped , double latency , double lag );
454
455
static void processXactStats (TState * thread , CState * st , instr_time * now ,
455
456
bool skipped , StatsData * agg );
@@ -780,7 +781,7 @@ mergeSimpleStats(SimpleStats *acc, SimpleStats *ss)
780
781
* the given value.
781
782
*/
782
783
static void
783
- initStats (StatsData * sd , double start_time )
784
+ initStats (StatsData * sd , time_t start_time )
784
785
{
785
786
sd -> start_time = start_time ;
786
787
sd -> cnt = 0 ;
@@ -2425,10 +2426,15 @@ doCustom(TState *thread, CState *st, StatsData *agg)
2425
2426
}
2426
2427
2427
2428
/*
2428
- * print log entry after completing one transaction.
2429
+ * Print log entry after completing one transaction.
2430
+ *
2431
+ * We print Unix-epoch timestamps in the log, so that entries can be
2432
+ * correlated against other logs. On some platforms this could be obtained
2433
+ * from the instr_time reading the caller has, but rather than get entangled
2434
+ * with that, we just eat the cost of an extra syscall in all cases.
2429
2435
*/
2430
2436
static void
2431
- doLog (TState * thread , CState * st , instr_time * now ,
2437
+ doLog (TState * thread , CState * st ,
2432
2438
StatsData * agg , bool skipped , double latency , double lag )
2433
2439
{
2434
2440
FILE * logfile = thread -> logfile ;
@@ -2447,15 +2453,17 @@ doLog(TState *thread, CState *st, instr_time *now,
2447
2453
if (agg_interval > 0 )
2448
2454
{
2449
2455
/*
2450
- * Loop until we reach the interval of the current transaction , and
2451
- * print all the empty intervals in between (this may happen with very
2452
- * low tps, e.g. --rate=0.1).
2456
+ * Loop until we reach the interval of the current moment , and print
2457
+ * any empty intervals in between (this may happen with very low tps,
2458
+ * e.g. --rate=0.1).
2453
2459
*/
2454
- while (agg -> start_time + agg_interval < INSTR_TIME_GET_DOUBLE (* now ))
2460
+ time_t now = time (NULL );
2461
+
2462
+ while (agg -> start_time + agg_interval <= now )
2455
2463
{
2456
2464
/* print aggregated report to logfile */
2457
2465
fprintf (logfile , "%ld " INT64_FORMAT " %.0f %.0f %.0f %.0f" ,
2458
- agg -> start_time ,
2466
+ ( long ) agg -> start_time ,
2459
2467
agg -> cnt ,
2460
2468
agg -> latency .sum ,
2461
2469
agg -> latency .sum2 ,
@@ -2485,12 +2493,6 @@ doLog(TState *thread, CState *st, instr_time *now,
2485
2493
/* no, print raw transactions */
2486
2494
struct timeval tv ;
2487
2495
2488
- /*
2489
- * We print the current system timestamp in the log, so that entries
2490
- * can be correlated against other logs. On some platforms this is
2491
- * available in *now, but rather than get entangled with that, we just
2492
- * eat the cost of an extra syscall in all cases.
2493
- */
2494
2496
gettimeofday (& tv , NULL );
2495
2497
if (skipped )
2496
2498
fprintf (logfile , "%d " INT64_FORMAT " skipped %d %ld %ld" ,
@@ -2518,7 +2520,7 @@ processXactStats(TState *thread, CState *st, instr_time *now,
2518
2520
10000
double latency = 0.0 ,
2519
2521
lag = 0.0 ;
2520
2522
2521
- if ((!skipped || agg_interval ) && INSTR_TIME_IS_ZERO (* now ))
2523
+ if ((!skipped ) && INSTR_TIME_IS_ZERO (* now ))
2522
2524
INSTR_TIME_SET_CURRENT (* now );
2523
2525
2524
2526
if (!skipped )
@@ -2540,7 +2542,7 @@ processXactStats(TState *thread, CState *st, instr_time *now,
2540
2542
thread -> stats .cnt ++ ;
2541
2543
2542
2544
if (use_log )
2543
- doLog (thread , st , now , agg , skipped , latency , lag );
2545
+ doLog (thread , st , agg , skipped , latency , lag );
2544
2546
2545
2547
/* XXX could use a mutex here, but we choose not to */
2546
2548
if (per_script_stats )
@@ -3202,7 +3204,7 @@ ParseScript(const char *script, const char *desc, int weight)
3202
3204
ps .desc = desc ;
3203
3205
ps .weight = weight ;
3204
3206
ps .commands = (Command * * ) pg_malloc (sizeof (Command * ) * alloc_num );
3205
- initStats (& ps .stats , 0.0 );
3207
+ initStats (& ps .stats , 0 );
3206
3208
3207
3209
/* Prepare to parse script */
3208
3210
sstate = psql_scan_create (& pgbench_callbacks );
@@ -3972,10 +3974,6 @@ main(int argc, char **argv)
3972
3974
}
3973
3975
break ;
3974
3976
case 5 :
3975
- #ifdef WIN32
3976
- fprintf (stderr , "--aggregate-interval is not currently supported on Windows\n" );
3977
- exit (1 );
3978
- #else
3979
3977
benchmarking_option_set = true;
3980
3978
agg_interval = atoi (optarg );
3981
3979
if (agg_interval <= 0 )
@@ -3984,7 +3982,6 @@ main(int argc, char **argv)
3984
3982
optarg );
3985
3983
exit (1 );
3986
3984
}
3987
- #endif
3988
3985
break ;
3989
3986
case 6 :
3990
3987
progress_timestamp = true;
@@ -4267,7 +4264,7 @@ main(int argc, char **argv)
4267
4264
thread -> random_state [2 ] = random ();
4268
4265
thread -> logfile = NULL ; /* filled in later */
4269
4266
thread -> latency_late = 0 ;
4270
- initStats (& thread -> stats , 0.0 );
4267
+ initStats (& thread -> stats , 0 );
4271
4268
4272
4269
nclients_dealt += thread -> nstate ;
4273
4270
}
@@ -4321,7 +4318,7 @@ main(int argc, char **argv)
4321
4318
#endif /* ENABLE_THREAD_SAFETY */
4322
4319
4323
4320
/* wait for threads and accumulate results */
4324
- initStats (& stats , 0.0 );
4321
+ initStats (& stats , 0 );
4325
4322
INSTR_TIME_SET_ZERO (conn_total_time );
4326
4323
for (i = 0 ; i < nthreads ; i ++ )
4327
4324
{
@@ -4394,6 +4391,9 @@ threadRun(void *arg)
4394
4391
4395
4392
INSTR_TIME_SET_ZERO (thread -> conn_time );
4396
4393
4394
+ initStats (& aggs , time (NULL ));
4395
+ last = aggs ;
4396
+
4397
4397
/* open log file if requested */
4398
4398
if (use_log )
4399
4399
{
@@ -4429,9 +4429,6 @@ threadRun(void *arg)
4429
4429
INSTR_TIME_SET_CURRENT (thread -> conn_time );
4430
4430
INSTR_TIME_SUBTRACT (thread -> conn_time , thread -> start_time );
4431
4431
4432
- initStats (& aggs , INSTR_TIME_GET_DOUBLE (thread -> start_time ));
4433
- last = aggs ;
4434
-
4435
4432
/* explicitly initialize the state machines */
4436
4433
for (i = 0 ; i < nstate ; i ++ )
4437
4434
{
@@ -4635,7 +4632,7 @@ threadRun(void *arg)
4635
4632
* (If a read from a 64-bit integer is not atomic, you might
4636
4633
* get a "torn" read and completely bogus latencies though!)
4637
4634
*/
4638
- initStats (& cur , 0.0 );
4635
+ initStats (& cur , 0 );
4639
4636
for (i = 0 ; i < nthreads ; i ++ )
4640
4637
{
4641
4638
mergeSimpleStats (& cur .latency , & thread [i ].stats .latency );
@@ -4695,12 +4692,13 @@ threadRun(void *arg)
4695
4692
INSTR_TIME_ACCUM_DIFF (thread -> conn_time , end , start );
4696
4693
if (thread -> logfile )
4697
4694
{
4698
- if (agg_interval )
4695
+ if (agg_interval > 0 )
4699
4696
{
4700
4697
/* log aggregated but not yet reported transactions */
4701
- doLog (thread , state , & end , & aggs , false, 0 , 0 );
4698
+ doLog (thread , state , & aggs , false, 0 , 0 );
4702
4699
}
4703
4700
fclose (thread -> logfile );
4701
+ thread -> logfile = NULL ;
4704
4702
}
4705
4703
return NULL ;
4706
4704
}
0 commit comments