Rework lwlocknames.txt to become lwlocklist.h
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 20 Mar 2024 10:46:11 +0000 (11:46 +0100)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Wed, 20 Mar 2024 10:55:20 +0000 (11:55 +0100)
This way, we can fold the list of lock names to occur in
BuiltinTrancheNames instead of having its own separate array.  This
saves two lines of code in GetLWTrancheName and some space in
BuiltinTrancheNames, as foreseen in commit 74a730631065, as well as
removing the need for a separate lwlocknames.c file.

We still have to build lwlocknames.h using Perl code, which initially I
wanted to avoid, but it gives us the chance to cross-check
wait_event_names.txt.

Discussion: https://postgr.es/m/202401231025.gbv4nnte5fmm@alvherre.pgsql

12 files changed:
src/backend/Makefile
src/backend/storage/lmgr/.gitignore
src/backend/storage/lmgr/Makefile
src/backend/storage/lmgr/generate-lwlocknames.pl
src/backend/storage/lmgr/lwlock.c
src/backend/storage/lmgr/lwlocknames.txt [deleted file]
src/backend/storage/lmgr/meson.build
src/backend/utils/activity/wait_event_names.txt
src/include/storage/lwlock.h
src/include/storage/lwlocklist.h [new file with mode: 0644]
src/include/storage/meson.build
src/tools/pginclude/headerscheck

index 3d7be095291d78330e4a627912966493bd7f2c54..6700aec0396294151e13383d48f6dc35830989cd 100644 (file)
@@ -110,8 +110,8 @@ $(top_builddir)/src/port/libpgport_srv.a: | submake-libpgport
 parser/gram.h: parser/gram.y
        $(MAKE) -C parser gram.h
 
-storage/lmgr/lwlocknames.h: storage/lmgr/generate-lwlocknames.pl storage/lmgr/lwlocknames.txt utils/activity/wait_event_names.txt
-       $(MAKE) -C storage/lmgr lwlocknames.h lwlocknames.c
+storage/lmgr/lwlocknames.h: storage/lmgr/generate-lwlocknames.pl ../include/storage/lwlocklist.h utils/activity/wait_event_names.txt
+       $(MAKE) -C storage/lmgr lwlocknames.h
 
 utils/activity/wait_event_types.h: utils/activity/generate-wait_event_types.pl utils/activity/wait_event_names.txt
        $(MAKE) -C utils/activity wait_event_types.h pgstat_wait_event.c wait_event_funcs_data.c
index dab4c3f580611a1495c14104582aae74e11e0460..8e5b734f15296927871ddbc0c6e743a38b4fc480 100644 (file)
@@ -1,3 +1,2 @@
-/lwlocknames.c
 /lwlocknames.h
 /s_lock_test
index 1aef423384c91fe2f09a32958c2f392335b3ad75..3f89548bde68db24e98b7de68e8422c08045f786 100644 (file)
@@ -18,7 +18,6 @@ OBJS = \
        lmgr.o \
        lock.o \
        lwlock.o \
-       lwlocknames.o \
        predicate.o \
        proc.o \
        s_lock.o \
@@ -35,11 +34,7 @@ s_lock_test: s_lock.c $(top_builddir)/src/common/libpgcommon.a $(top_builddir)/s
                $(TASPATH) -L $(top_builddir)/src/common -lpgcommon \
                -L $(top_builddir)/src/port -lpgport -lm -o s_lock_test
 
-# see notes in src/backend/parser/Makefile
-lwlocknames.c: lwlocknames.h
-       touch $@
-
-lwlocknames.h: $(top_srcdir)/src/backend/storage/lmgr/lwlocknames.txt $(top_srcdir)/src/backend/utils/activity/wait_event_names.txt generate-lwlocknames.pl
+lwlocknames.h: ../../../include/storage/lwlocklist.h ../../utils/activity/wait_event_names.txt generate-lwlocknames.pl
        $(PERL) $(srcdir)/generate-lwlocknames.pl $^
 
 check: s_lock_test
@@ -47,4 +42,4 @@ check: s_lock_test
 
 clean:
        rm -f s_lock_test
-       rm -f lwlocknames.h lwlocknames.c
+       rm -f lwlocknames.h
index 7b93ecf6c1e306a90bc34350ec22aed3eee49cf8..eaddd9d3b976f4f4a1a6d0f256d4fdb2eedcba29 100644 (file)
@@ -1,6 +1,6 @@
 #!/usr/bin/perl
 #
-# Generate lwlocknames.h and lwlocknames.c from lwlocknames.txt
+# Generate lwlocknames.h from lwlocklist.h
 # Copyright (c) 2000-2024, PostgreSQL Global Development Group
 
 use strict;
@@ -14,26 +14,22 @@ my $continue = "\n";
 
 GetOptions('outdir:s' => \$output_path);
 
-open my $lwlocknames, '<', $ARGV[0] or die;
+open my $lwlocklist, '<', $ARGV[0] or die;
 open my $wait_event_names, '<', $ARGV[1] or die;
 
 # Include PID in suffix in case parallel make runs this multiple times.
 my $htmp = "$output_path/lwlocknames.h.tmp$$";
-my $ctmp = "$output_path/lwlocknames.c.tmp$$";
 open my $h, '>', $htmp or die "Could not open $htmp: $!";
-open my $c, '>', $ctmp or die "Could not open $ctmp: $!";
 
 my $autogen =
-  "/* autogenerated from src/backend/storage/lmgr/lwlocknames.txt, do not edit */\n";
+  "/* autogenerated from src/include/storage/lwlocklist.h, 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 "const char *const IndividualLWLockNames[] = {";
 
 #
 # First, record the predefined LWLocks listed in wait_event_names.txt.  We'll
-# cross-check those with the ones in lwlocknames.txt.
+# cross-check those with the ones in lwlocklist.h.
 #
 my @wait_event_lwlocks;
 my $record_lwlocks = 0;
@@ -61,66 +57,70 @@ while (<$wait_event_names>)
 
        # Record the LWLock.
        (my $waiteventname, my $waitevendocsentence) = split(/\t/, $_);
-       push(@wait_event_lwlocks, $waiteventname . "Lock");
+       push(@wait_event_lwlocks, $waiteventname);
 }
 
+my $in_comment = 0;
 my $i = 0;
-while (<$lwlocknames>)
+while (<$lwlocklist>)
 {
        chomp;
 
-       # Skip comments
-       next if /^#/;
+       # Skip single-line C comments and empty lines
+       next if m{^\s*/\*.*\*/$};
        next if /^\s*$/;
 
-       die "unable to parse lwlocknames.txt"
-         unless /^(\w+)\s+(\d+)$/;
+       # skip multiline C comments
+       if ($in_comment == 1)
+       {
+               $in_comment = 0 if m{\*/};
+               next;
+       }
+       elsif (m{^\s*/\*})
+       {
+               $in_comment = 1;
+               next;
+       }
 
-       (my $lockname, my $lockidx) = ($1, $2);
+       die "unable to parse lwlocklist.h line \"$_\""
+         unless /^PG_LWLOCK\((\d+),\s+(\w+)\)$/;
 
-       my $trimmedlockname = $lockname;
-       $trimmedlockname =~ s/Lock$//;
-       die "lock names must end with 'Lock'" if $trimmedlockname eq $lockname;
+       (my $lockidx, my $lockname) = ($1, $2);
 
-       die "lwlocknames.txt not in order" if $lockidx < $lastlockidx;
-       die "lwlocknames.txt has duplicates" if $lockidx == $lastlockidx;
+       die "lwlocklist.h not in order" if $lockidx < $lastlockidx;
+       die "lwlocklist.h has duplicates" if $lockidx == $lastlockidx;
 
-       die "$lockname defined in lwlocknames.txt but missing from "
+       die "$lockname defined in lwlocklist.h but missing from "
          . "wait_event_names.txt"
          if $i >= scalar @wait_event_lwlocks;
        die "lists of predefined LWLocks do not match (first mismatch at "
          . "$wait_event_lwlocks[$i] in wait_event_names.txt and $lockname in "
-         . "lwlocknames.txt)"
+         . "lwlocklist.h)"
          if $wait_event_lwlocks[$i] ne $lockname;
        $i++;
 
        while ($lastlockidx < $lockidx - 1)
        {
                ++$lastlockidx;
-               printf $c "%s   \"<unassigned:%d>\"", $continue, $lastlockidx;
                $continue = ",\n";
        }
-       printf $c "%s   \"%s\"", $continue, $trimmedlockname;
        $lastlockidx = $lockidx;
        $continue = ",\n";
 
-       print $h "#define $lockname (&MainLWLockArray[$lockidx].lock)\n";
+       print $h "#define ${lockname}Lock (&MainLWLockArray[$lockidx].lock)\n";
 }
 
 die
   "$wait_event_lwlocks[$i] defined in wait_event_names.txt but missing from "
-  . "lwlocknames.txt"
+  . "lwlocklist.h"
   if $i < scalar @wait_event_lwlocks;
 
-printf $c "\n};\n";
 print $h "\n";
 printf $h "#define NUM_INDIVIDUAL_LWLOCKS              %s\n", $lastlockidx + 1;
 
 close $h;
-close $c;
 
 rename($htmp, "$output_path/lwlocknames.h")
   || die "rename: $htmp to $output_path/lwlocknames.h: $!";
-rename($ctmp, "$output_path/lwlocknames.c") || die "rename: $ctmp: $!";
 
-close $lwlocknames;
+close $lwlocklist;
index 30f3a09a4ce9f3379261cec8e7f60fd9ba7aa751..83992725de3eb18111036ac6e11409fef41db356 100644 (file)
@@ -112,8 +112,8 @@ StaticAssertDecl(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS,
  * There are three sorts of LWLock "tranches":
  *
  * 1. The individually-named locks defined in lwlocknames.h each have their
- * own tranche.  The names of these tranches appear in IndividualLWLockNames[]
- * in lwlocknames.c.
+ * own tranche.  We absorb the names of these tranches from there into
+ * BuiltinTrancheNames here.
  *
  * 2. There are some predefined tranches for built-in groups of locks.
  * These are listed in enum BuiltinTrancheIds in lwlock.h, and their names
@@ -126,9 +126,10 @@ StaticAssertDecl(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS,
  * All these names are user-visible as wait event names, so choose with care
  * ... and do not forget to update the documentation's list of wait events.
  */
-extern const char *const IndividualLWLockNames[];      /* in lwlocknames.c */
-
 static const char *const BuiltinTrancheNames[] = {
+#define PG_LWLOCK(id, lockname) [id] = CppAsString(lockname) "Lock",
+#include "storage/lwlocklist.h"
+#undef PG_LWLOCK
        [LWTRANCHE_XACT_BUFFER] = "XactBuffer",
        [LWTRANCHE_COMMITTS_BUFFER] = "CommitTsBuffer",
        [LWTRANCHE_SUBTRANS_BUFFER] = "SubtransBuffer",
@@ -742,11 +743,7 @@ LWLockReportWaitEnd(void)
 static const char *
 GetLWTrancheName(uint16 trancheId)
 {
-       /* Individual LWLock? */
-       if (trancheId < NUM_INDIVIDUAL_LWLOCKS)
-               return IndividualLWLockNames[trancheId];
-
-       /* Built-in tranche? */
+       /* Built-in tranche or individual LWLock? */
        if (trancheId < LWTRANCHE_FIRST_USER_DEFINED)
                return BuiltinTrancheNames[trancheId];
 
diff --git a/src/backend/storage/lmgr/lwlocknames.txt b/src/backend/storage/lmgr/lwlocknames.txt
deleted file mode 100644 (file)
index 284d168..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-# 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.  Also, do not forget to update the section
-# WaitEventLWLock of src/backend/utils/activity/wait_event_names.txt.
-
-# 0 is available; was formerly BufFreelistLock
-ShmemIndexLock                                         1
-OidGenLock                                                     2
-XidGenLock                                                     3
-ProcArrayLock                                          4
-SInvalReadLock                                         5
-SInvalWriteLock                                                6
-WALBufMappingLock                                      7
-WALWriteLock                                           8
-ControlFileLock                                                9
-# 10 was CheckpointLock
-# 11 was XactSLRULock
-# 12 was SubtransSLRULock
-MultiXactGenLock                                       13
-# 14 was MultiXactOffsetSLRULock
-# 15 was MultiXactMemberSLRULock
-RelCacheInitLock                                       16
-CheckpointerCommLock                           17
-TwoPhaseStateLock                                      18
-TablespaceCreateLock                           19
-BtreeVacuumLock                                                20
-AddinShmemInitLock                                     21
-AutovacuumLock                                         22
-AutovacuumScheduleLock                         23
-SyncScanLock                                           24
-RelationMappingLock                                    25
-#26 was NotifySLRULock
-NotifyQueueLock                                                27
-SerializableXactHashLock                       28
-SerializableFinishedListLock           29
-SerializablePredicateListLock          30
-# 31 was SerialSLRULock
-SyncRepLock                                                    32
-BackgroundWorkerLock                           33
-DynamicSharedMemoryControlLock         34
-AutoFileLock                                           35
-ReplicationSlotAllocationLock          36
-ReplicationSlotControlLock                     37
-#38 was CommitTsSLRULock
-CommitTsLock                                           39
-ReplicationOriginLock                          40
-MultiXactTruncationLock                                41
-# 42 was OldSnapshotTimeMapLock
-LogicalRepWorkerLock                           43
-XactTruncationLock                                     44
-# 45 was XactTruncationLock until removal of BackendRandomLock
-WrapLimitsVacuumLock                           46
-NotifyQueueTailLock                                    47
-WaitEventExtensionLock                         48
-WALSummarizerLock                                      49
-DSMRegistryLock                                                50
-InjectionPointLock                             51
-SerialControlLock                                      52
index da32198f788ce411fa65e816f55deb088a1e104e..05ac41e809a81b4203fae98fc04dc93f8f2467ab 100644 (file)
@@ -11,5 +11,3 @@ backend_sources += files(
   's_lock.c',
   'spin.c',
 )
-
-generated_backend_sources += lwlocknames[1]
index c08e00d1d6a713293e5c1592a1659ca4aa7aad72..8d0571a03d109ab2f3ed035e907f8df3aab43806 100644 (file)
@@ -280,9 +280,9 @@ Extension   "Waiting in an extension."
 # This class of wait events has its own set of C structure, so these are
 # only used for the documentation.
 #
-# NB: Predefined LWLocks (i.e., those declared in lwlocknames.txt) must be
+# NB: Predefined LWLocks (i.e., those declared in lwlocklist.h) must be
 # listed in the top section of locks and must be listed in the same order as in
-# lwlocknames.txt.
+# lwlocklist.h.
 #
 
 Section: ClassName - WaitEventLWLock
@@ -333,9 +333,9 @@ SerialControl       "Waiting to read or update shared <filename>pg_serial</filename> s
 #
 # END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
 #
-# Predefined LWLocks (i.e., those declared in lwlocknames.txt) must be listed
+# Predefined LWLocks (i.e., those declared in lwlocknames.h) must be listed
 # in the section above and must be listed in the same order as in
-# lwlocknames.txt.  Other LWLocks must be listed in the section below.
+# lwlocknames.h.  Other LWLocks must be listed in the section below.
 #
 
 XactBuffer     "Waiting for I/O on a transaction status SLRU buffer."
index 10bea8c5950cf95cc7c27a0a75ce6b90e5478bdd..3479b4cf522893739c78bbe42ffe047d510f22a1 100644 (file)
@@ -19,6 +19,7 @@
 #endif
 
 #include "port/atomics.h"
+#include "storage/lwlocknames.h"
 #include "storage/proclist_types.h"
 
 struct PGPROC;
@@ -82,9 +83,6 @@ typedef struct NamedLWLockTranche
 extern PGDLLIMPORT NamedLWLockTranche *NamedLWLockTrancheArray;
 extern PGDLLIMPORT int NamedLWLockTrancheRequests;
 
-/* Names for fixed lwlocks */
-#include "storage/lwlocknames.h"
-
 /*
  * It's a bit odd to declare NUM_BUFFER_PARTITIONS and NUM_LOCK_PARTITIONS
  * here, but we need them to figure out offsets within MainLWLockArray, and
diff --git a/src/include/storage/lwlocklist.h b/src/include/storage/lwlocklist.h
new file mode 100644 (file)
index 0000000..85f6568
--- /dev/null
@@ -0,0 +1,85 @@
+/*-------------------------------------------------------------------------
+ *
+ * lwlocklist.h
+ *
+ * The predefined LWLock list is kept in its own source file for use by
+ * automatic tools.  The exact representation of a keyword is determined by
+ * the PG_LWLOCK macro, which is not defined in this file; it can be
+ * defined by the caller for special purposes.
+ *
+ * Also, generate-lwlocknames.pl processes this file to create lwlocknames.h.
+ *
+ * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * IDENTIFICATION
+ *    src/include/storage/lwlocklist.h
+ *
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * 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.  Also, do not forget to update the section
+ * WaitEventLWLock of src/backend/utils/activity/wait_event_names.txt.
+ *
+ * Note that the names here don't include the Lock suffix, to appease the
+ * C preprocessor; it's added elsewhere.
+ */
+
+/* 0 is available; was formerly BufFreelistLock */
+PG_LWLOCK(1, ShmemIndex)
+PG_LWLOCK(2, OidGen)
+PG_LWLOCK(3, XidGen)
+PG_LWLOCK(4, ProcArray)
+PG_LWLOCK(5, SInvalRead)
+PG_LWLOCK(6, SInvalWrite)
+PG_LWLOCK(7, WALBufMapping)
+PG_LWLOCK(8, WALWrite)
+PG_LWLOCK(9, ControlFile)
+/* 10 was CheckpointLock */
+/* 11 was XactSLRULock */
+/* 12 was SubtransSLRULock */
+PG_LWLOCK(13, MultiXactGen)
+/* 14 was MultiXactOffsetSLRULock */
+/* 15 was MultiXactMemberSLRULock */
+PG_LWLOCK(16, RelCacheInit)
+PG_LWLOCK(17, CheckpointerComm)
+PG_LWLOCK(18, TwoPhaseState)
+PG_LWLOCK(19, TablespaceCreate)
+PG_LWLOCK(20, BtreeVacuum)
+PG_LWLOCK(21, AddinShmemInit)
+PG_LWLOCK(22, Autovacuum)
+PG_LWLOCK(23, AutovacuumSchedule)
+PG_LWLOCK(24, SyncScan)
+PG_LWLOCK(25, RelationMapping)
+/* 26 was NotifySLRULock */
+PG_LWLOCK(27, NotifyQueue)
+PG_LWLOCK(28, SerializableXactHash)
+PG_LWLOCK(29, SerializableFinishedList)
+PG_LWLOCK(30, SerializablePredicateList)
+/* 31 was SerialSLRULock */
+PG_LWLOCK(32, SyncRep)
+PG_LWLOCK(33, BackgroundWorker)
+PG_LWLOCK(34, DynamicSharedMemoryControl)
+PG_LWLOCK(35, AutoFile)
+PG_LWLOCK(36, ReplicationSlotAllocation)
+PG_LWLOCK(37, ReplicationSlotControl)
+/* 38 was CommitTsSLRULock */
+PG_LWLOCK(39, CommitTs)
+PG_LWLOCK(40, ReplicationOrigin)
+PG_LWLOCK(41, MultiXactTruncation)
+/* 42 was OldSnapshotTimeMapLock */
+PG_LWLOCK(43, LogicalRepWorker)
+PG_LWLOCK(44, XactTruncation)
+/* 45 was XactTruncationLock until removal of BackendRandomLock */
+PG_LWLOCK(46, WrapLimitsVacuum)
+PG_LWLOCK(47, NotifyQueueTail)
+PG_LWLOCK(48, WaitEventExtension)
+PG_LWLOCK(49, WALSummarizer)
+PG_LWLOCK(50, DSMRegistry)
+PG_LWLOCK(51, InjectionPoint)
+PG_LWLOCK(52, SerialControl)
index 666fb22408e2edaeea01409071d26c1ac86d2b63..f889093117e3931a76163eb31b234f7d0b9d7508 100644 (file)
@@ -1,10 +1,10 @@
 # Copyright (c) 2022-2024, PostgreSQL Global Development Group
 
-lwlocknames = custom_target('lwlocknames',
+lwlocknames_h = custom_target('lwlocknames_h',
   input: files(
-    '../../backend/storage/lmgr/lwlocknames.txt',
+    '../../include/storage/lwlocklist.h',
     '../../backend/utils/activity/wait_event_names.txt'),
-  output: ['lwlocknames.h', 'lwlocknames.c'],
+  output: ['lwlocknames.h'],
   command: [
     perl, files('../../backend/storage/lmgr/generate-lwlocknames.pl'),
     '-o', '@OUTDIR@',
@@ -12,12 +12,10 @@ lwlocknames = custom_target('lwlocknames',
   ],
   build_by_default: true,
   install: true,
-  install_dir: [dir_include_server / 'storage', false],
+  install_dir: dir_include_server / 'storage',
 )
 
-lwlocknames_h = lwlocknames[0]
-
 generated_backend_headers += lwlocknames_h
 
 # autoconf generates the file there, ensure we get a conflict
-generated_sources_ac += {'src/backend/storage/lmgr': ['lwlocknames.c', 'lwlocknames.h']}
+generated_sources_ac += {'src/backend/storage/lmgr': ['lwlocknames.h']}
index a59be39307e33bd980b3d5bf59db585213f445dc..4a157d0a5f259f97a1e6c6f933568e87ed722f51 100755 (executable)
@@ -133,6 +133,7 @@ do
        test "$f" = src/interfaces/ecpg/preproc/c_kwlist.h && continue
        test "$f" = src/interfaces/ecpg/preproc/ecpg_kwlist.h && continue
        test "$f" = src/include/regex/regerrs.h && continue
+       test "$f" = src/include/storage/lwlocklist.h && continue
        test "$f" = src/include/tcop/cmdtaglist.h && continue
        test "$f" = src/pl/plpgsql/src/plerrcodes.h && continue
        test "$f" = src/pl/plpython/spiexceptions.h && continue