Track spinlock delay in microsecond granularity.
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
This commit is contained in:
parent
9db4ad44eb
commit
9e0bc7c1e8
@ -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
|
* 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
|
* the probability of unintended failure) than to fix the total time
|
||||||
* spent.
|
* 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 MIN_SPINS_PER_DELAY 10
|
||||||
#define MAX_SPINS_PER_DELAY 1000
|
#define MAX_SPINS_PER_DELAY 1000
|
||||||
#define NUM_DELAYS 1000
|
#define NUM_DELAYS 1000
|
||||||
#define MIN_DELAY_MSEC 1
|
#define MIN_DELAY_USEC 1000L
|
||||||
#define MAX_DELAY_MSEC 1000
|
#define MAX_DELAY_USEC 1000000L
|
||||||
|
|
||||||
int spins = 0;
|
int spins = 0;
|
||||||
int delays = 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);
|
s_lock_stuck(lock, file, line);
|
||||||
|
|
||||||
if (cur_delay == 0) /* first time to delay? */
|
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)
|
#if defined(S_LOCK_TEST)
|
||||||
fprintf(stdout, "*");
|
fprintf(stdout, "*");
|
||||||
@ -122,8 +117,8 @@ s_lock(volatile slock_t *lock, const char *file, int line)
|
|||||||
cur_delay += (int) (cur_delay *
|
cur_delay += (int) (cur_delay *
|
||||||
((double) random() / (double) MAX_RANDOM_VALUE) + 0.5);
|
((double) random() / (double) MAX_RANDOM_VALUE) + 0.5);
|
||||||
/* wrap back to minimum delay when max is exceeded */
|
/* wrap back to minimum delay when max is exceeded */
|
||||||
if (cur_delay > MAX_DELAY_MSEC)
|
if (cur_delay > MAX_DELAY_USEC)
|
||||||
cur_delay = MIN_DELAY_MSEC;
|
cur_delay = MIN_DELAY_USEC;
|
||||||
|
|
||||||
spins = 0;
|
spins = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user