Track spinlock delay in microsecond granularity.
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 28 Jun 2013 09:30:55 +0000 (12:30 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Fri, 28 Jun 2013 09:39:55 +0000 (12:39 +0300)
On many platforms the OS will round the sleep time to millisecond
resolution, but there is no reason for us to pre-emptively round the
argument to pg_usleep.

When the delay was measured in milliseconds and started from 1 ms, it
sometimes took many attempts until the logic that increases the delay by
multiplying with a random value between 1 and 2 actually managed to bump it
from 1 ms to 2 ms. That lead to a sequence of 1 ms waits until the delay
started to increase. This wasn't really a problem but it looked odd if you
observed the waits. There is no measurable difference in performance, but
it's more readable this way.

Jeff Janes

src/backend/storage/lmgr/s_lock.c

index ed1f56aa8b63c35a14c348b71db65ade306ef0dd..940b6865d24914e5b51659a786229eb8f6035af0 100644 (file)
@@ -81,17 +81,12 @@ s_lock(volatile slock_t *lock, const char *file, int line)
     * so minutes.  It seems better to fix the total number of tries (and thus
     * the probability of unintended failure) than to fix the total time
     * spent.
-    *
-    * The pg_usleep() delays are measured in milliseconds because 1 msec is a
-    * common resolution limit at the OS level for newer platforms. On older
-    * platforms the resolution limit is usually 10 msec, in which case the
-    * total delay before timeout will be a bit more.
     */
 #define MIN_SPINS_PER_DELAY 10
 #define MAX_SPINS_PER_DELAY 1000
 #define NUM_DELAYS         1000
-#define MIN_DELAY_MSEC     1
-#define MAX_DELAY_MSEC     1000
+#define MIN_DELAY_USEC     1000L
+#define MAX_DELAY_USEC     1000000L
 
    int         spins = 0;
    int         delays = 0;
@@ -109,9 +104,9 @@ s_lock(volatile slock_t *lock, const char *file, int line)
                s_lock_stuck(lock, file, line);
 
            if (cur_delay == 0) /* first time to delay? */
-               cur_delay = MIN_DELAY_MSEC;
+               cur_delay = MIN_DELAY_USEC;
 
-           pg_usleep(cur_delay * 1000L);
+           pg_usleep(cur_delay);
 
 #if defined(S_LOCK_TEST)
            fprintf(stdout, "*");
@@ -122,8 +117,8 @@ s_lock(volatile slock_t *lock, const char *file, int line)
            cur_delay += (int) (cur_delay *
                      ((double) random() / (double) MAX_RANDOM_VALUE) + 0.5);
            /* wrap back to minimum delay when max is exceeded */
-           if (cur_delay > MAX_DELAY_MSEC)
-               cur_delay = MIN_DELAY_MSEC;
+           if (cur_delay > MAX_DELAY_USEC)
+               cur_delay = MIN_DELAY_USEC;
 
            spins = 0;
        }