pgbench: When -T is used, don't wait for transactions beyond end of run.
authorRobert Haas <rhaas@postgresql.org>
Wed, 9 Mar 2016 18:09:12 +0000 (13:09 -0500)
committerRobert Haas <rhaas@postgresql.org>
Wed, 9 Mar 2016 18:11:05 +0000 (13:11 -0500)
At low rates, this can lead to pgbench taking significantly longer to
terminate than the user might expect.  Repair.

Fabien Coelho, reviewed by Aleksander Alekseev, Álvaro Herrera, and me.

src/bin/pgbench/pgbench.c

index 92df7504ad57e5aafe0cff3c424d220db4d70647..e3d0d69b3f2b865163dc6ca69b372a8fd3d00e84 100644 (file)
@@ -94,6 +94,7 @@ static int    pthread_join(pthread_t th, void **thread_return);
 
 int                    nxacts = 0;                     /* number of transactions per client */
 int                    duration = 0;           /* duration in seconds */
+int64          end_time = 0;           /* when to stop in micro seconds, under -T */
 
 /*
  * scaling factor. for example, scale = 10 will make 1000000 tuples in
@@ -1362,6 +1363,10 @@ top:
                thread->throttle_trigger += wait;
                st->txn_scheduled = thread->throttle_trigger;
 
+               /* stop client if next transaction is beyond pgbench end of execution */
+               if (duration > 0 && st->txn_scheduled > end_time)
+                       return clientDone(st, true);
+
                /*
                 * If this --latency-limit is used, and this slot is already late so
                 * that the transaction will miss the latency limit even if it
@@ -3582,6 +3587,11 @@ main(int argc, char **argv)
 
                INSTR_TIME_SET_CURRENT(thread->start_time);
 
+               /* compute when to stop */
+               if (duration > 0)
+                       end_time = INSTR_TIME_GET_MICROSEC(thread->start_time) +
+                               (int64) 1000000 * duration;
+
                /* the first thread (i = 0) is executed by main thread */
                if (i > 0)
                {
@@ -3600,6 +3610,10 @@ main(int argc, char **argv)
        }
 #else
        INSTR_TIME_SET_CURRENT(threads[0].start_time);
+       /* compute when to stop */
+       if (duration > 0)
+               end_time = INSTR_TIME_GET_MICROSEC(threads[0].start_time) +
+                       (int64) 1000000 * duration;
        threads[0].thread = INVALID_THREAD;
 #endif   /* ENABLE_THREAD_SAFETY */