]> granicus.if.org Git - postgresql/commitdiff
When trace_lwlocks is used, identify individual lwlocks by name.
authorRobert Haas <rhaas@postgresql.org>
Fri, 11 Sep 2015 17:58:28 +0000 (13:58 -0400)
committerRobert Haas <rhaas@postgresql.org>
Fri, 11 Sep 2015 18:01:39 +0000 (14:01 -0400)
Naming the individual lwlocks seems like something that may be useful
for other types of debugging, monitoring, or instrumentation output,
but this commit just implements it for the specific case of
trace_lwlocks.

Patch by me, reviewed by Amit Kapila and Kyotaro Horiguchi

src/backend/Makefile
src/backend/storage/lmgr/.gitignore [new file with mode: 0644]
src/backend/storage/lmgr/Makefile
src/backend/storage/lmgr/generate-lwlocknames.pl [new file with mode: 0644]
src/backend/storage/lmgr/lwlock.c
src/backend/storage/lmgr/lwlocknames.txt [new file with mode: 0644]
src/include/storage/.gitignore [new file with mode: 0644]
src/include/storage/lwlock.h
src/tools/msvc/Solution.pm

index 98b978f3da47572f5651fbd4a4fd5f67361ac436..f872deb188b42c7c010c9dd32c7ab238a067be57 100644 (file)
@@ -106,7 +106,7 @@ endif
 endif # aix
 
 # Update the commonly used headers before building the subdirectories
-$(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/catalog/schemapg.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/errcodes.h $(top_builddir)/src/include/utils/probes.h
+$(SUBDIRS:%=%-recursive): $(top_builddir)/src/include/parser/gram.h $(top_builddir)/src/include/catalog/schemapg.h $(top_builddir)/src/include/storage/lwlocknames.h $(top_builddir)/src/include/utils/fmgroids.h $(top_builddir)/src/include/utils/errcodes.h $(top_builddir)/src/include/utils/probes.h
 
 # run this unconditionally to avoid needing to know its dependencies here:
 submake-schemapg:
@@ -135,6 +135,9 @@ postgres.o: $(OBJS)
 parser/gram.h: parser/gram.y
        $(MAKE) -C parser gram.h
 
+storage/lmgr/lwlocknames.h: storage/lmgr/generate-lwlocknames.pl storage/lmgr/lwlocknames.txt
+       $(MAKE) -C storage/lmgr lwlocknames.h
+
 utils/fmgroids.h: utils/Gen_fmgrtab.pl catalog/Catalog.pm $(top_srcdir)/src/include/catalog/pg_proc.h
        $(MAKE) -C utils fmgroids.h
 
@@ -165,6 +168,11 @@ $(top_builddir)/src/include/catalog/schemapg.h: catalog/schemapg.h
          cd '$(dir $@)' && rm -f $(notdir $@) && \
          $(LN_S) "$$prereqdir/$(notdir $<)" .
 
+$(top_builddir)/src/include/storage/lwlocknames.h: storage/lmgr/lwlocknames.h
+       prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \
+         cd '$(dir $@)' && rm -f $(notdir $@) && \
+         $(LN_S) "$$prereqdir/$(notdir $<)" .
+
 $(top_builddir)/src/include/utils/errcodes.h: utils/errcodes.h
        prereqdir=`cd '$(dir $<)' >/dev/null && pwd` && \
          cd '$(dir $@)' && rm -f $(notdir $@) && \
@@ -192,6 +200,7 @@ distprep:
        $(MAKE) -C bootstrap    bootparse.c bootscanner.c
        $(MAKE) -C catalog      schemapg.h postgres.bki postgres.description postgres.shdescription
        $(MAKE) -C replication  repl_gram.c repl_scanner.c
+       $(MAKE) -C storage      lwlocknames.h
        $(MAKE) -C utils        fmgrtab.c fmgroids.h errcodes.h
        $(MAKE) -C utils/misc   guc-file.c
        $(MAKE) -C utils/sort   qsort_tuple.c
@@ -282,6 +291,7 @@ clean:
        rm -f $(LOCALOBJS) postgres$(X) $(POSTGRES_IMP) \
                $(top_builddir)/src/include/parser/gram.h \
                $(top_builddir)/src/include/catalog/schemapg.h \
+               $(top_builddir)/src/include/storage/lwlocknames.h \
                $(top_builddir)/src/include/utils/fmgroids.h \
                $(top_builddir)/src/include/utils/probes.h
 ifeq ($(PORTNAME), cygwin)
@@ -307,6 +317,8 @@ maintainer-clean: distclean
              catalog/postgres.shdescription \
              replication/repl_gram.c \
              replication/repl_scanner.c \
+             storage/lmgr/lwlocknames.c \
+             storage/lmgr/lwlocknames.h \
              utils/fmgroids.h \
              utils/fmgrtab.c \
              utils/errcodes.h \
diff --git a/src/backend/storage/lmgr/.gitignore b/src/backend/storage/lmgr/.gitignore
new file mode 100644 (file)
index 0000000..9355cae
--- /dev/null
@@ -0,0 +1,2 @@
+/lwlocknames.c
+/lwlocknames.h
index e12a8549f741020944ba81b583cd7ab66e3f0a6e..3ad7535d74d7671082d36be494bc1de6b4659157 100644 (file)
@@ -24,8 +24,17 @@ s_lock_test: s_lock.c $(top_builddir)/src/port/libpgport.a
        $(CC) $(CPPFLAGS) $(CFLAGS) -DS_LOCK_TEST=1 $(srcdir)/s_lock.c \
                $(TASPATH) -L $(top_builddir)/src/port -lpgport -o s_lock_test
 
+# see explanation in ../../parser/Makefile
+lwlocknames.c: lwlocknames.h ;
+
+lwlocknames.h: $(top_srcdir)/src/backend/storage/lmgr/lwlocknames.txt generate-lwlocknames.pl
+       $(PERL) $(srcdir)/generate-lwlocknames.pl $<
+
 check: s_lock_test
        ./s_lock_test
 
-clean distclean maintainer-clean:
+clean distclean:
        rm -f s_lock_test
+
+maintainer-clean: clean
+       rm -f lwlocknames.h lwlocknames.c
diff --git a/src/backend/storage/lmgr/generate-lwlocknames.pl b/src/backend/storage/lmgr/generate-lwlocknames.pl
new file mode 100644 (file)
index 0000000..3af2347
--- /dev/null
@@ -0,0 +1,67 @@
+#!/usr/bin/perl
+#
+# Generate lwlocknames.h and lwlocknames.c from lwlocknames.txt
+# Copyright (c) 2000-2015, PostgreSQL Global Development Group
+
+use warnings;
+use strict;
+
+my $lastlockidx = -1;
+my $continue = "\n";
+
+open my $lwlocknames, $ARGV[0] or die;
+
+# Include PID in suffix in case parallel make runs this multiple times.
+my $htmp = "lwlocknames.h.tmp$$";
+my $ctmp = "lwlocknames.c.tmp$$";
+open H, '>', $htmp or die "Could not open $htmp: $!";
+open C, '>', $ctmp or die "Could not open $ctmp: $!";
+
+my $autogen =
+       "/* autogenerated from src/backend/storage/lmgr/lwlocknames.txt, do not edit */\n";
+print H $autogen;
+print H "/* there is deliberately not an #ifndef LWLOCKNAMES_H here */\n\n";
+print C $autogen, "\n";
+
+print C "static char *MainLWLockNames[] = {";
+
+while (<$lwlocknames>)
+{
+       chomp;
+
+       # Skip comments
+       next if /^#/;
+       next if /^\s*$/;
+
+       die "unable to parse lwlocknames.txt"
+         unless /^(\w+)\s+(\d+)$/;
+
+       (my $lockname, my $lockidx) = ($1, $2);
+
+       die "lwlocknames.txt not in order" if $lockidx < $lastlockidx;
+       die "lwlocknames.txt has duplicates" if $lockidx == $lastlockidx;
+
+       while ($lastlockidx < $lockidx - 1)
+       {
+               ++$lastlockidx;
+               printf C "%s    \"<unassigned:%d>\"", $continue, $lastlockidx;
+               $continue = ",\n";
+       }
+       printf C "%s    \"%s\"", $continue, $lockname;
+       $lastlockidx = $lockidx;
+       $continue = ",\n";
+
+       print H "#define $lockname (&MainLWLockArray[$lockidx].lock)\n";
+}
+
+printf C "\n};\n";
+print H "\n";
+printf H "#define NUM_INDIVIDUAL_LWLOCKS               %s\n", $lastlockidx + 1;
+
+close H;
+close C;
+
+rename($htmp, 'lwlocknames.h') || die "rename: $htmp: $!";
+rename($ctmp, 'lwlocknames.c') || die "rename: $ctmp: $!";
+
+close $lwlocknames;
index 687ed6399cb19ed3183bb75a0214b57229e05675..db10a96123002b0b91fc99f7bb1abd28003a46e4 100644 (file)
@@ -95,6 +95,9 @@
 #include "utils/hsearch.h"
 #endif
 
+/* Constants for lwlock names */
+#include "lwlocknames.c"
+
 
 /* We use the ShmemLock spinlock to protect LWLockAssign */
 extern slock_t *ShmemLock;
@@ -183,18 +186,32 @@ PRINT_LWDEBUG(const char *where, LWLock *lock, LWLockMode mode)
        if (Trace_lwlocks)
        {
                uint32          state = pg_atomic_read_u32(&lock->state);
-
-               ereport(LOG,
-                               (errhidestmt(true),
-                                errhidecontext(true),
-                                errmsg("%d: %s(%s %d): excl %u shared %u haswaiters %u waiters %u rOK %d",
-                                               MyProcPid,
-                                               where, T_NAME(lock), T_ID(lock),
-                                               !!(state & LW_VAL_EXCLUSIVE),
-                                               state & LW_SHARED_MASK,
-                                               !!(state & LW_FLAG_HAS_WAITERS),
-                                               pg_atomic_read_u32(&lock->nwaiters),
-                                               !!(state & LW_FLAG_RELEASE_OK))));
+               int                     id = T_ID(lock);
+
+               if (lock->tranche == 0 && id < NUM_INDIVIDUAL_LWLOCKS)
+                       ereport(LOG,
+                                       (errhidestmt(true),
+                                        errhidecontext(true),
+                                        errmsg("%d: %s(%s): excl %u shared %u haswaiters %u waiters %u rOK %d",
+                                                       MyProcPid,
+                                                       where, MainLWLockNames[id],
+                                                       !!(state & LW_VAL_EXCLUSIVE),
+                                                       state & LW_SHARED_MASK,
+                                                       !!(state & LW_FLAG_HAS_WAITERS),
+                                                       pg_atomic_read_u32(&lock->nwaiters),
+                                                       !!(state & LW_FLAG_RELEASE_OK))));
+               else
+                       ereport(LOG,
+                                       (errhidestmt(true),
+                                        errhidecontext(true),
+                                        errmsg("%d: %s(%s %d): excl %u shared %u haswaiters %u waiters %u rOK %d",
+                                                       MyProcPid,
+                                                       where, T_NAME(lock), id,
+                                                       !!(state & LW_VAL_EXCLUSIVE),
+                                                       state & LW_SHARED_MASK,
+                                                       !!(state & LW_FLAG_HAS_WAITERS),
+                                                       pg_atomic_read_u32(&lock->nwaiters),
+                                                       !!(state & LW_FLAG_RELEASE_OK))));
        }
 }
 
@@ -204,11 +221,20 @@ LOG_LWDEBUG(const char *where, LWLock *lock, const char *msg)
        /* hide statement & context here, otherwise the log is just too verbose */
        if (Trace_lwlocks)
        {
-               ereport(LOG,
-                               (errhidestmt(true),
-                                errhidecontext(true),
-                                errmsg("%s(%s %d): %s", where,
-                                               T_NAME(lock), T_ID(lock), msg)));
+               int                     id = T_ID(lock);
+
+               if (lock->tranche == 0 && id < NUM_INDIVIDUAL_LWLOCKS)
+                       ereport(LOG,
+                                       (errhidestmt(true),
+                                        errhidecontext(true),
+                                        errmsg("%s(%s): %s", where,
+                                                       MainLWLockNames[id], msg)));
+               else
+                       ereport(LOG,
+                                       (errhidestmt(true),
+                                        errhidecontext(true),
+                                        errmsg("%s(%s %d): %s", where,
+                                                       T_NAME(lock), id, msg)));
        }
 }
 
diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt
new file mode 100644 (file)
index 0000000..96bbfe8
--- /dev/null
@@ -0,0 +1,47 @@
+# Some commonly-used locks have predefined positions within MainLWLockArray;
+# these are defined here.  If you add a lock, add it to the end to avoid
+# renumbering the existing locks; if you remove a lock, consider leaving a gap
+# in the numbering sequence for the benefit of DTrace and other external
+# debugging scripts.
+
+# 0 is available; was formerly BufFreelistLock
+ShmemIndexLock                                         1
+OidGenLock                                                     2
+XidGenLock                                                     3
+ProcArrayLock                                          4
+SInvalReadLock                                         5
+SInvalWriteLock                                                6
+WALBufMappingLock                                      7
+WALWriteLock                                           8
+ControlFileLock                                                9
+CheckpointLock                                         10
+CLogControlLock                                                11
+SubtransControlLock                                    12
+MultiXactGenLock                                       13
+MultiXactOffsetControlLock                     14
+MultiXactMemberControlLock                     15
+RelCacheInitLock                                       16
+CheckpointerCommLock                           17
+TwoPhaseStateLock                                      18
+TablespaceCreateLock                           19
+BtreeVacuumLock                                                20
+AddinShmemInitLock                                     21
+AutovacuumLock                                         22
+AutovacuumScheduleLock                         23
+SyncScanLock                                           24
+RelationMappingLock                                    25
+AsyncCtlLock                                           26
+AsyncQueueLock                                         27
+SerializableXactHashLock                       28
+SerializableFinishedListLock           29
+SerializablePredicateLockListLock      30
+OldSerXidLock                                          31
+SyncRepLock                                                    32
+BackgroundWorkerLock                           33
+DynamicSharedMemoryControlLock         34
+AutoFileLock                                           35
+ReplicationSlotAllocationLock          36
+ReplicationSlotControlLock                     37
+CommitTsControlLock                                    38
+CommitTsLock                                           39
+ReplicationOriginLock                          40
diff --git a/src/include/storage/.gitignore b/src/include/storage/.gitignore
new file mode 100644 (file)
index 0000000..209c8be
--- /dev/null
@@ -0,0 +1 @@
+/lwlocknames.h
index 84a6fc7fa01c27a442e7b917cdd58eac3d803813..00435b062f004a386cc3c60c590c059a6dfe6616 100644 (file)
@@ -91,56 +91,8 @@ typedef union LWLockPadded
 } LWLockPadded;
 extern PGDLLIMPORT LWLockPadded *MainLWLockArray;
 
-/*
- * Some commonly-used locks have predefined positions within MainLWLockArray;
- * defining macros here makes it much easier to keep track of these.  If you
- * add a lock, add it to the end to avoid renumbering the existing locks;
- * if you remove a lock, consider leaving a gap in the numbering sequence for
- * the benefit of DTrace and other external debugging scripts.
- */
-/* 0 is available; was formerly BufFreelistLock */
-#define ShmemIndexLock                         (&MainLWLockArray[1].lock)
-#define OidGenLock                                     (&MainLWLockArray[2].lock)
-#define XidGenLock                                     (&MainLWLockArray[3].lock)
-#define ProcArrayLock                          (&MainLWLockArray[4].lock)
-#define SInvalReadLock                         (&MainLWLockArray[5].lock)
-#define SInvalWriteLock                                (&MainLWLockArray[6].lock)
-#define WALBufMappingLock                      (&MainLWLockArray[7].lock)
-#define WALWriteLock                           (&MainLWLockArray[8].lock)
-#define ControlFileLock                                (&MainLWLockArray[9].lock)
-#define CheckpointLock                         (&MainLWLockArray[10].lock)
-#define CLogControlLock                                (&MainLWLockArray[11].lock)
-#define SubtransControlLock                    (&MainLWLockArray[12].lock)
-#define MultiXactGenLock                       (&MainLWLockArray[13].lock)
-#define MultiXactOffsetControlLock     (&MainLWLockArray[14].lock)
-#define MultiXactMemberControlLock     (&MainLWLockArray[15].lock)
-#define RelCacheInitLock                       (&MainLWLockArray[16].lock)
-#define CheckpointerCommLock           (&MainLWLockArray[17].lock)
-#define TwoPhaseStateLock                      (&MainLWLockArray[18].lock)
-#define TablespaceCreateLock           (&MainLWLockArray[19].lock)
-#define BtreeVacuumLock                                (&MainLWLockArray[20].lock)
-#define AddinShmemInitLock                     (&MainLWLockArray[21].lock)
-#define AutovacuumLock                         (&MainLWLockArray[22].lock)
-#define AutovacuumScheduleLock         (&MainLWLockArray[23].lock)
-#define SyncScanLock                           (&MainLWLockArray[24].lock)
-#define RelationMappingLock                    (&MainLWLockArray[25].lock)
-#define AsyncCtlLock                           (&MainLWLockArray[26].lock)
-#define AsyncQueueLock                         (&MainLWLockArray[27].lock)
-#define SerializableXactHashLock       (&MainLWLockArray[28].lock)
-#define SerializableFinishedListLock           (&MainLWLockArray[29].lock)
-#define SerializablePredicateLockListLock      (&MainLWLockArray[30].lock)
-#define OldSerXidLock                          (&MainLWLockArray[31].lock)
-#define SyncRepLock                                    (&MainLWLockArray[32].lock)
-#define BackgroundWorkerLock           (&MainLWLockArray[33].lock)
-#define DynamicSharedMemoryControlLock         (&MainLWLockArray[34].lock)
-#define AutoFileLock                           (&MainLWLockArray[35].lock)
-#define ReplicationSlotAllocationLock  (&MainLWLockArray[36].lock)
-#define ReplicationSlotControlLock             (&MainLWLockArray[37].lock)
-#define CommitTsControlLock                    (&MainLWLockArray[38].lock)
-#define CommitTsLock                           (&MainLWLockArray[39].lock)
-#define ReplicationOriginLock          (&MainLWLockArray[40].lock)
-
-#define NUM_INDIVIDUAL_LWLOCKS         41
+/* Names for fixed lwlocks */
+#include "lwlocknames.h"
 
 /*
  * It's a bit odd to declare NUM_BUFFER_PARTITIONS and NUM_LOCK_PARTITIONS
index 6b16e69b69015c3e5129650baf41fd36f2c9acba..1564b728090cd0240bdf5756fa03a7663b6c1248 100644 (file)
@@ -285,6 +285,22 @@ s{PG_VERSION_STR "[^"]+"}{__STRINGIFY(x) #x\n#define __STRINGIFY2(z) __STRINGIFY
                        'src/include/utils/fmgroids.h');
        }
 
+       if (IsNewer(
+                       'src/include/storage/lwlocknames.h', 'src/backend/storage/lmgr/lwlocknames.txt'))
+       {
+               print "Generating lwlocknames.c and lwlocknames.h...\n";
+               chdir('src/backend/storage/lmgr');
+               system('perl generate-lwlocknames.pl lwlocknames.txt');
+               chdir('../../../..');
+       }
+       if (IsNewer(
+                       'src/include/storage/lwlocknames.h',
+                       'src/backend/storage/lmgr/lwlocknames.h'))
+       {
+               copyFile('src/backend/storage/lmgr/lwlocknames.h',
+                       'src/include/storage/lwlocknames.h');
+       }
+
        if (IsNewer('src/include/utils/probes.h', 'src/backend/utils/probes.d'))
        {
                print "Generating probes.h...\n";