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 (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to