Commit b79ab001 authored by Robert Haas's avatar Robert Haas

When LWLOCK_STATS is defined, count spindelays.

When LWLOCK_STATS is *not* defined, the only change is that
SpinLockAcquire now returns the number of delays.

Patch by me, review by Jeff Janes.
parent 75777360
...@@ -95,6 +95,7 @@ static int counts_for_pid = 0; ...@@ -95,6 +95,7 @@ static int counts_for_pid = 0;
static int *sh_acquire_counts; static int *sh_acquire_counts;
static int *ex_acquire_counts; static int *ex_acquire_counts;
static int *block_counts; static int *block_counts;
static int *spin_delay_counts;
#endif #endif
#ifdef LOCK_DEBUG #ifdef LOCK_DEBUG
...@@ -134,6 +135,7 @@ init_lwlock_stats(void) ...@@ -134,6 +135,7 @@ init_lwlock_stats(void)
sh_acquire_counts = calloc(numLocks, sizeof(int)); sh_acquire_counts = calloc(numLocks, sizeof(int));
ex_acquire_counts = calloc(numLocks, sizeof(int)); ex_acquire_counts = calloc(numLocks, sizeof(int));
spin_delay_counts = calloc(numLocks, sizeof(int));
block_counts = calloc(numLocks, sizeof(int)); block_counts = calloc(numLocks, sizeof(int));
counts_for_pid = MyProcPid; counts_for_pid = MyProcPid;
on_shmem_exit(print_lwlock_stats, 0); on_shmem_exit(print_lwlock_stats, 0);
...@@ -151,10 +153,10 @@ print_lwlock_stats(int code, Datum arg) ...@@ -151,10 +153,10 @@ print_lwlock_stats(int code, Datum arg)
for (i = 0; i < numLocks; i++) for (i = 0; i < numLocks; i++)
{ {
if (sh_acquire_counts[i] || ex_acquire_counts[i] || block_counts[i]) if (sh_acquire_counts[i] || ex_acquire_counts[i] || block_counts[i] || spin_delay_counts[i])
fprintf(stderr, "PID %d lwlock %d: shacq %u exacq %u blk %u\n", fprintf(stderr, "PID %d lwlock %d: shacq %u exacq %u blk %u spindelay %u\n",
MyProcPid, i, sh_acquire_counts[i], ex_acquire_counts[i], MyProcPid, i, sh_acquire_counts[i], ex_acquire_counts[i],
block_counts[i]); block_counts[i], spin_delay_counts[i]);
} }
LWLockRelease(0); LWLockRelease(0);
...@@ -395,7 +397,11 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode) ...@@ -395,7 +397,11 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
bool mustwait; bool mustwait;
/* Acquire mutex. Time spent holding mutex should be short! */ /* Acquire mutex. Time spent holding mutex should be short! */
#ifdef LWLOCK_STATS
spin_delay_counts[lockid] += SpinLockAcquire(&lock->mutex);
#else
SpinLockAcquire(&lock->mutex); SpinLockAcquire(&lock->mutex);
#endif
/* If retrying, allow LWLockRelease to release waiters again */ /* If retrying, allow LWLockRelease to release waiters again */
if (retry) if (retry)
......
...@@ -46,7 +46,7 @@ s_lock_stuck(volatile slock_t *lock, const char *file, int line) ...@@ -46,7 +46,7 @@ s_lock_stuck(volatile slock_t *lock, const char *file, int line)
/* /*
* s_lock(lock) - platform-independent portion of waiting for a spinlock. * s_lock(lock) - platform-independent portion of waiting for a spinlock.
*/ */
void int
s_lock(volatile slock_t *lock, const char *file, int line) s_lock(volatile slock_t *lock, const char *file, int line)
{ {
/* /*
...@@ -155,6 +155,7 @@ s_lock(volatile slock_t *lock, const char *file, int line) ...@@ -155,6 +155,7 @@ s_lock(volatile slock_t *lock, const char *file, int line)
if (spins_per_delay > MIN_SPINS_PER_DELAY) if (spins_per_delay > MIN_SPINS_PER_DELAY)
spins_per_delay = Max(spins_per_delay - 1, MIN_SPINS_PER_DELAY); spins_per_delay = Max(spins_per_delay - 1, MIN_SPINS_PER_DELAY);
} }
return delays;
} }
......
...@@ -12,10 +12,11 @@ ...@@ -12,10 +12,11 @@
* void S_INIT_LOCK(slock_t *lock) * void S_INIT_LOCK(slock_t *lock)
* Initialize a spinlock (to the unlocked state). * Initialize a spinlock (to the unlocked state).
* *
* void S_LOCK(slock_t *lock) * int S_LOCK(slock_t *lock)
* Acquire a spinlock, waiting if necessary. * Acquire a spinlock, waiting if necessary.
* Time out and abort() if unable to acquire the lock in a * Time out and abort() if unable to acquire the lock in a
* "reasonable" amount of time --- typically ~ 1 minute. * "reasonable" amount of time --- typically ~ 1 minute.
* Should return number of "delays"; see s_lock.c
* *
* void S_UNLOCK(slock_t *lock) * void S_UNLOCK(slock_t *lock)
* Unlock a previously acquired lock. * Unlock a previously acquired lock.
...@@ -978,10 +979,7 @@ extern int tas_sema(volatile slock_t *lock); ...@@ -978,10 +979,7 @@ extern int tas_sema(volatile slock_t *lock);
#if !defined(S_LOCK) #if !defined(S_LOCK)
#define S_LOCK(lock) \ #define S_LOCK(lock) \
do { \ (TAS(lock) ? s_lock((lock), __FILE__, __LINE__) : 0)
if (TAS(lock)) \
s_lock((lock), __FILE__, __LINE__); \
} while (0)
#endif /* S_LOCK */ #endif /* S_LOCK */
#if !defined(S_LOCK_FREE) #if !defined(S_LOCK_FREE)
...@@ -1015,7 +1013,7 @@ extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or ...@@ -1015,7 +1013,7 @@ extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or
/* /*
* Platform-independent out-of-line support routines * Platform-independent out-of-line support routines
*/ */
extern void s_lock(volatile slock_t *lock, const char *file, int line); extern int s_lock(volatile slock_t *lock, const char *file, int line);
/* Support for dynamic adjustment of spins_per_delay */ /* Support for dynamic adjustment of spins_per_delay */
#define DEFAULT_SPINS_PER_DELAY 100 #define DEFAULT_SPINS_PER_DELAY 100
......
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