Commit 396ef156 authored by Heikki Linnakangas's avatar Heikki Linnakangas

Fix busy-wait in pgbench, with --rate.

If --rate was used to throttle pgbench, it failed to sleep when it had
nothing to do, leading to a busy-wait with 100% CPU usage. This bug was
introduced in the refactoring in v10. Before that, sleep() was called with
a timeout, even when there were no file descriptors to wait for.

Reported by Jeff Janes, patch by Fabien COELHO. Backpatch to v10.

Discussion: https://www.postgresql.org/message-id/CAMkU%3D1x5hoX0pLLKPRnXCy0T8uHoDvXdq%2B7kAM9eoC9_z72ucw%40mail.gmail.com
parent 2632bcce
...@@ -4578,11 +4578,13 @@ threadRun(void *arg) ...@@ -4578,11 +4578,13 @@ threadRun(void *arg)
* or it's time to print a progress report. Update input_mask to show * or it's time to print a progress report. Update input_mask to show
* which client(s) received data. * which client(s) received data.
*/ */
if (min_usec > 0 && maxsock != -1) if (min_usec > 0)
{ {
int nsocks; /* return from select(2) */ int nsocks = 0; /* return from select(2) if called */
if (min_usec != PG_INT64_MAX) if (min_usec != PG_INT64_MAX)
{
if (maxsock != -1)
{ {
struct timeval timeout; struct timeval timeout;
...@@ -4590,8 +4592,16 @@ threadRun(void *arg) ...@@ -4590,8 +4592,16 @@ threadRun(void *arg)
timeout.tv_usec = min_usec % 1000000; timeout.tv_usec = min_usec % 1000000;
nsocks = select(maxsock + 1, &input_mask, NULL, NULL, &timeout); nsocks = select(maxsock + 1, &input_mask, NULL, NULL, &timeout);
} }
else else /* nothing active, simple sleep */
{
pg_usleep(min_usec);
}
}
else /* no explicit delay, select without timeout */
{
nsocks = select(maxsock + 1, &input_mask, NULL, NULL, NULL); nsocks = select(maxsock + 1, &input_mask, NULL, NULL, NULL);
}
if (nsocks < 0) if (nsocks < 0)
{ {
if (errno == EINTR) if (errno == EINTR)
...@@ -4604,7 +4614,7 @@ threadRun(void *arg) ...@@ -4604,7 +4614,7 @@ threadRun(void *arg)
goto done; goto done;
} }
} }
else else /* min_usec == 0, i.e. something needs to be executed */
{ {
/* If we didn't call select(), don't try to read any data */ /* If we didn't call select(), don't try to read any data */
FD_ZERO(&input_mask); FD_ZERO(&input_mask);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment