1515 * Portions Copyright (c) 1994, Regents of the University of California
1616 *
1717 * IDENTIFICATION
18- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.38 2006/03/05 15:58:39 momjian Exp $
18+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.39 2006/04/21 16:45:12 tgl Exp $
1919 *
2020 *-------------------------------------------------------------------------
2121 */
2525#include "access/multixact.h"
2626#include "access/subtrans.h"
2727#include "miscadmin.h"
28+ #include "storage/ipc.h"
2829#include "storage/lwlock.h"
2930#include "storage/proc.h"
3031#include "storage/spin.h"
@@ -84,6 +85,13 @@ NON_EXEC_STATIC LWLockPadded *LWLockArray = NULL;
8485static int num_held_lwlocks = 0 ;
8586static LWLockId held_lwlocks [MAX_SIMUL_LWLOCKS ];
8687
88+ #ifdef LWLOCK_STATS
89+ static int counts_for_pid = 0 ;
90+ static int * sh_acquire_counts ;
91+ static int * ex_acquire_counts ;
92+ static int * block_counts ;
93+ #endif
94+
8795
8896#ifdef LOCK_DEBUG
8997bool Trace_lwlocks = false;
@@ -109,6 +117,31 @@ LOG_LWDEBUG(const char *where, LWLockId lockid, const char *msg)
109117#define LOG_LWDEBUG (a ,b ,c )
110118#endif /* LOCK_DEBUG */
111119
120+ #ifdef LWLOCK_STATS
121+
122+ static void
123+ print_lwlock_stats (int code , Datum arg )
124+ {
125+ int i ;
126+ int * LWLockCounter = (int * ) ((char * ) LWLockArray - 2 * sizeof (int ));
127+ int numLocks = LWLockCounter [1 ];
128+
129+ /* Grab an LWLock to keep different backends from mixing reports */
130+ LWLockAcquire (0 , LW_EXCLUSIVE );
131+
132+ for (i = 0 ; i < numLocks ; i ++ )
133+ {
134+ if (sh_acquire_counts [i ] || ex_acquire_counts [i ] || block_counts [i ])
135+ fprintf (stderr , "PID %d lwlock %d: shacq %u exacq %u blk %u\n" ,
136+ MyProcPid , i , sh_acquire_counts [i ], ex_acquire_counts [i ],
137+ block_counts [i ]);
138+ }
139+
140+ LWLockRelease (0 );
141+ }
142+
143+ #endif /* LWLOCK_STATS */
144+
112145
113146/*
114147 * Compute number of LWLocks to allocate.
@@ -263,6 +296,26 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
263296
264297 PRINT_LWDEBUG ("LWLockAcquire" , lockid , lock );
265298
299+ #ifdef LWLOCK_STATS
300+ /* Set up local count state first time through in a given process */
301+ if (counts_for_pid != MyProcPid )
302+ {
303+ int * LWLockCounter = (int * ) ((char * ) LWLockArray - 2 * sizeof (int ));
304+ int numLocks = LWLockCounter [1 ];
305+
306+ sh_acquire_counts = calloc (numLocks , sizeof (int ));
307+ ex_acquire_counts = calloc (numLocks , sizeof (int ));
308+ block_counts = calloc (numLocks , sizeof (int ));
309+ counts_for_pid = MyProcPid ;
310+ on_shmem_exit (print_lwlock_stats , 0 );
311+ }
312+ /* Count lock acquisition attempts */
313+ if (mode == LW_EXCLUSIVE )
314+ ex_acquire_counts [lockid ]++ ;
315+ else
316+ sh_acquire_counts [lockid ]++ ;
317+ #endif /* LWLOCK_STATS */
318+
266319 /*
267320 * We can't wait if we haven't got a PGPROC. This should only occur
268321 * during bootstrap or shared memory initialization. Put an Assert here
@@ -369,6 +422,10 @@ LWLockAcquire(LWLockId lockid, LWLockMode mode)
369422 */
370423 LOG_LWDEBUG ("LWLockAcquire" , lockid , "waiting" );
371424
425+ #ifdef LWLOCK_STATS
426+ block_counts [lockid ]++ ;
427+ #endif
428+
372429 for (;;)
373430 {
374431 /* "false" means cannot accept cancel/die interrupt here. */
0 commit comments