Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Cross-check lists of predefined LWLocks.
authorNathan Bossart <nathan@postgresql.org>
Tue, 9 Jan 2024 17:05:19 +0000 (11:05 -0600)
committerNathan Bossart <nathan@postgresql.org>
Tue, 9 Jan 2024 17:05:19 +0000 (11:05 -0600)
Both lwlocknames.txt and wait_event_names.txt contain a list of all
the predefined LWLocks, i.e., those with predefined positions
within MainLWLockArray.  It is easy to miss one or the other,
especially since the list in wait_event_names.txt omits the "Lock"
suffix from all the LWLock wait events.  This commit adds a cross-
check of these lists to the script that generates lwlocknames.h.
If the lists do not match exactly, building will fail.

Suggested-by: Robert Haas
Reviewed-by: Robert Haas, Michael Paquier, Bertrand Drouvot
Discussion: https://postgr.es/m/20240102173120.GA1061678%40nathanxps13

src/backend/Makefile
src/backend/storage/lmgr/Makefile
src/backend/storage/lmgr/generate-lwlocknames.pl
src/backend/utils/activity/wait_event_names.txt
src/include/storage/meson.build

index 816461aa17ec3a1e855d61cfc6335835bef49fad..7d2ea7d54a665989ad4faec10411bb6b7d8c5d47 100644 (file)
@@ -130,7 +130,7 @@ $(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
+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
 
 utils/activity/wait_event_types.h: utils/activity/generate-wait_event_types.pl utils/activity/wait_event_names.txt
index c48ba943c4c9cf52ebff27aff60f743a62e1a53b..504480e8477a535a2021893ae670b38a3851057f 100644 (file)
@@ -39,8 +39,8 @@ s_lock_test: s_lock.c $(top_builddir)/src/common/libpgcommon.a $(top_builddir)/s
 lwlocknames.c: lwlocknames.h
    touch $@
 
-lwlocknames.h: $(top_srcdir)/src/backend/storage/lmgr/lwlocknames.txt generate-lwlocknames.pl
-   $(PERL) $(srcdir)/generate-lwlocknames.pl $<
+lwlocknames.h: $(top_srcdir)/src/backend/storage/lmgr/lwlocknames.txt $(top_srcdir)/src/backend/utils/activity/wait_event_names.txt generate-lwlocknames.pl
+   $(PERL) $(srcdir)/generate-lwlocknames.pl $^
 
 check: s_lock_test
    ./s_lock_test
index bef5e16e1144b9df3c0734fc308d7142a207abae..7b93ecf6c1e306a90bc34350ec22aed3eee49cf8 100644 (file)
@@ -15,6 +15,7 @@ my $continue = "\n";
 GetOptions('outdir:s' => \$output_path);
 
 open my $lwlocknames, '<', $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$$";
@@ -30,6 +31,40 @@ 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.
+#
+my @wait_event_lwlocks;
+my $record_lwlocks = 0;
+
+while (<$wait_event_names>)
+{
+   chomp;
+
+   # Check for end marker.
+   last if /^# END OF PREDEFINED LWLOCKS/;
+
+   # Skip comments and empty lines.
+   next if /^#/;
+   next if /^\s*$/;
+
+   # Start recording LWLocks when we find the WaitEventLWLock section.
+   if (/^Section: ClassName - WaitEventLWLock$/)
+   {
+       $record_lwlocks = 1;
+       next;
+   }
+
+   # Go to the next line if we are not yet recording LWLocks.
+   next if not $record_lwlocks;
+
+   # Record the LWLock.
+   (my $waiteventname, my $waitevendocsentence) = split(/\t/, $_);
+   push(@wait_event_lwlocks, $waiteventname . "Lock");
+}
+
+my $i = 0;
 while (<$lwlocknames>)
 {
    chomp;
@@ -50,6 +85,15 @@ while (<$lwlocknames>)
    die "lwlocknames.txt not in order" if $lockidx < $lastlockidx;
    die "lwlocknames.txt has duplicates" if $lockidx == $lastlockidx;
 
+   die "$lockname defined in lwlocknames.txt 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)"
+     if $wait_event_lwlocks[$i] ne $lockname;
+   $i++;
+
    while ($lastlockidx < $lockidx - 1)
    {
        ++$lastlockidx;
@@ -63,6 +107,11 @@ while (<$lwlocknames>)
    print $h "#define $lockname (&MainLWLockArray[$lockidx].lock)\n";
 }
 
+die
+  "$wait_event_lwlocks[$i] defined in wait_event_names.txt but missing from "
+  . "lwlocknames.txt"
+  if $i < scalar @wait_event_lwlocks;
+
 printf $c "\n};\n";
 print $h "\n";
 printf $h "#define NUM_INDIVIDUAL_LWLOCKS      %s\n", $lastlockidx + 1;
index 088eb977d4081798b5104540b39070a054a975d8..f625473ad4375f4154f9e88a23d6b0f513f94ffc 100644 (file)
@@ -276,6 +276,10 @@ 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
+# listed in the top section of locks and must be listed in the same order as in
+# lwlocknames.txt.
+#
 
 Section: ClassName - WaitEventLWLock
 
@@ -326,6 +330,14 @@ NotifyQueueTail    "Waiting to update limit on <command>NOTIFY</command> message st
 WaitEventExtension "Waiting to read or update custom wait events information for extensions."
 WALSummarizer  "Waiting to read or update WAL summarization state."
 
+#
+# END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE)
+#
+# Predefined LWLocks (i.e., those declared in lwlocknames.txt) 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.
+#
+
 XactBuffer "Waiting for I/O on a transaction status SLRU buffer."
 CommitTsBuffer "Waiting for I/O on a commit timestamp SLRU buffer."
 SubtransBuffer "Waiting for I/O on a sub-transaction SLRU buffer."
index 2a88248464e8c84e3df735c7640d5f3d7ff68534..666fb22408e2edaeea01409071d26c1ac86d2b63 100644 (file)
@@ -1,7 +1,9 @@
 # Copyright (c) 2022-2024, PostgreSQL Global Development Group
 
 lwlocknames = custom_target('lwlocknames',
-  input: files('../../backend/storage/lmgr/lwlocknames.txt'),
+  input: files(
+    '../../backend/storage/lmgr/lwlocknames.txt',
+    '../../backend/utils/activity/wait_event_names.txt'),
   output: ['lwlocknames.h', 'lwlocknames.c'],
   command: [
     perl, files('../../backend/storage/lmgr/generate-lwlocknames.pl'),