On 09/16/2015 10:25 AM, Jesper Pedersen wrote:
Likely from LWLOCK_STATS' own lwlock.c::print_lwlock_stats, which would
make sense.
Version 3 attached, which ignores entries from MainLWLockArray[0].
Best regards,
Jesper
*** /tmp/NTwtmh_lwlock.c 2015-09-16 10:34:02.955957192 -0400
--- src/backend/storage/lmgr/lwlock.c 2015-09-16 10:32:18.088843413 -0400
***************
*** 163,172 ****
--- 163,175 ----
{
lwlock_stats_key key;
int sh_acquire_count;
+ int sh_acquire_max;
int ex_acquire_count;
+ int ex_acquire_max;
int block_count;
int dequeue_self_count;
int spin_delay_count;
+ int max_waiters;
} lwlock_stats;
static HTAB *lwlock_stats_htab;
***************
*** 297,308 ****
while ((lwstats = (lwlock_stats *) hash_seq_search(&scan)) != NULL)
{
! fprintf(stderr,
! "PID %d lwlock %s %d: shacq %u exacq %u blk %u spindelay %u dequeue self %u\n",
! MyProcPid, LWLockTrancheArray[lwstats->key.tranche]->name,
! lwstats->key.instance, lwstats->sh_acquire_count,
! lwstats->ex_acquire_count, lwstats->block_count,
! lwstats->spin_delay_count, lwstats->dequeue_self_count);
}
LWLockRelease(&MainLWLockArray[0].lock);
--- 300,325 ----
while ((lwstats = (lwlock_stats *) hash_seq_search(&scan)) != NULL)
{
! if (lwstats->key.tranche == 0 && lwstats->key.instance < NUM_INDIVIDUAL_LWLOCKS)
! {
! /* We ignore information from MainLWLockArray[0] since it isn't in real use */
! if (lwstats->key.instance != 0)
! fprintf(stderr,
! "PID %d lwlock %s: shacq %u shmax %u exacq %u exmax %u blk %u spindelay %u dequeue self %u maxw %u\n",
! MyProcPid, MainLWLockNames[lwstats->key.instance],
! lwstats->sh_acquire_count, lwstats->sh_acquire_max,
! lwstats->ex_acquire_count, lwstats->ex_acquire_max,
! lwstats->block_count, lwstats->spin_delay_count, lwstats->dequeue_self_count,
! lwstats->max_waiters);
! }
! else
! fprintf(stderr,
! "PID %d lwlock %s %d: shacq %u shmax %u exacq %u exmax %u blk %u spindelay %u dequeue self %u maxw %u\n",
! MyProcPid, LWLockTrancheArray[lwstats->key.tranche]->name,
! lwstats->key.instance, lwstats->sh_acquire_count, lwstats->sh_acquire_max,
! lwstats->ex_acquire_count, lwstats->ex_acquire_max,
! lwstats->block_count, lwstats->spin_delay_count, lwstats->dequeue_self_count,
! lwstats->max_waiters);
}
LWLockRelease(&MainLWLockArray[0].lock);
***************
*** 330,339 ****
--- 347,359 ----
if (!found)
{
lwstats->sh_acquire_count = 0;
+ lwstats->sh_acquire_max = 0;
lwstats->ex_acquire_count = 0;
+ lwstats->ex_acquire_max = 0;
lwstats->block_count = 0;
lwstats->dequeue_self_count = 0;
lwstats->spin_delay_count = 0;
+ lwstats->max_waiters = 0;
}
return lwstats;
}
***************
*** 774,779 ****
--- 794,802 ----
LWLockQueueSelf(LWLock *lock, LWLockMode mode)
{
#ifdef LWLOCK_STATS
+ bool include;
+ int counter, size;
+ dlist_iter iter;
lwlock_stats *lwstats;
lwstats = get_lwlock_stats_entry(lock);
***************
*** 792,797 ****
--- 815,860 ----
#ifdef LWLOCK_STATS
lwstats->spin_delay_count += SpinLockAcquire(&lock->mutex);
+
+ /*
+ * We scan the list of waiters from the back in order to find
+ * out how many of the same lock type are waiting for a lock.
+ * Similar types have the potential to be groupped together.
+ *
+ * We also count the number of waiters, including ourself.
+ */
+ include = true;
+ size = 1;
+ counter = 1;
+
+ dlist_reverse_foreach(iter, &lock->waiters)
+ {
+ if (include)
+ {
+ PGPROC *waiter = dlist_container(PGPROC, lwWaitLink, iter.cur);
+
+ if (waiter->lwWaitMode == mode)
+ counter += 1;
+ else
+ include = false;
+ }
+
+ size += 1;
+ }
+
+ if (mode == LW_EXCLUSIVE || mode == LW_WAIT_UNTIL_FREE)
+ {
+ if (counter > lwstats->ex_acquire_max)
+ lwstats->ex_acquire_max = counter;
+ }
+ else if (mode == LW_SHARED)
+ {
+ if (counter > lwstats->sh_acquire_max)
+ lwstats->sh_acquire_max = counter;
+ }
+
+ if (size > lwstats->max_waiters)
+ lwstats->max_waiters = size;
#else
SpinLockAcquire(&lock->mutex);
#endif
***************
*** 943,951 ****
--- 1006,1022 ----
#ifdef LWLOCK_STATS
/* Count lock acquisition attempts */
if (mode == LW_EXCLUSIVE)
+ {
lwstats->ex_acquire_count++;
+ if (lwstats->ex_acquire_max == 0)
+ lwstats->ex_acquire_max = 1;
+ }
else
+ {
lwstats->sh_acquire_count++;
+ if (lwstats->sh_acquire_max == 0)
+ lwstats->sh_acquire_max = 1;
+ }
#endif /* LWLOCK_STATS */
/*
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers