diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2017-10-01 09:29:27 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2017-10-01 09:29:27 +0300 |
commit | 396ef1561878a5d42ea9191f60098b7fbbec6e41 (patch) | |
tree | 868a11b9fc6243b82184d1f1f984d8600447e048 /src | |
parent | 2632bcce5e767a2b5901bbef54ae52df061eee72 (diff) | |
download | postgresql-396ef1561878a5d42ea9191f60098b7fbbec6e41.tar.gz postgresql-396ef1561878a5d42ea9191f60098b7fbbec6e41.zip |
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
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/pgbench/pgbench.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index f0394136902..5d8a01c72cf 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -4578,20 +4578,30 @@ threadRun(void *arg) * or it's time to print a progress report. Update input_mask to show * 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) { - struct timeval timeout; + if (maxsock != -1) + { + struct timeval timeout; - timeout.tv_sec = min_usec / 1000000; - timeout.tv_usec = min_usec % 1000000; - nsocks = select(maxsock + 1, &input_mask, NULL, NULL, &timeout); + timeout.tv_sec = min_usec / 1000000; + timeout.tv_usec = min_usec % 1000000; + nsocks = select(maxsock + 1, &input_mask, NULL, NULL, &timeout); + } + else /* nothing active, simple sleep */ + { + pg_usleep(min_usec); + } } - else + else /* no explicit delay, select without timeout */ + { nsocks = select(maxsock + 1, &input_mask, NULL, NULL, NULL); + } + if (nsocks < 0) { if (errno == EINTR) @@ -4604,7 +4614,7 @@ threadRun(void *arg) 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 */ FD_ZERO(&input_mask); |