Cross-check lists of predefined LWLocks.

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
pull/152/head
Nathan Bossart 2 years ago
parent a7be2a6c26
commit 5b1b9bce84
  1. 2
      src/backend/Makefile
  2. 4
      src/backend/storage/lmgr/Makefile
  3. 49
      src/backend/storage/lmgr/generate-lwlocknames.pl
  4. 12
      src/backend/utils/activity/wait_event_names.txt
  5. 4
      src/include/storage/meson.build

@ -130,7 +130,7 @@ $(top_builddir)/src/port/libpgport_srv.a: | submake-libpgport
parser/gram.h: parser/gram.y parser/gram.h: parser/gram.y
$(MAKE) -C parser gram.h $(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 $(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 utils/activity/wait_event_types.h: utils/activity/generate-wait_event_types.pl utils/activity/wait_event_names.txt

@ -39,8 +39,8 @@ s_lock_test: s_lock.c $(top_builddir)/src/common/libpgcommon.a $(top_builddir)/s
lwlocknames.c: lwlocknames.h lwlocknames.c: lwlocknames.h
touch $@ touch $@
lwlocknames.h: $(top_srcdir)/src/backend/storage/lmgr/lwlocknames.txt 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 $< $(PERL) $(srcdir)/generate-lwlocknames.pl $^
check: s_lock_test check: s_lock_test
./s_lock_test ./s_lock_test

@ -15,6 +15,7 @@ my $continue = "\n";
GetOptions('outdir:s' => \$output_path); GetOptions('outdir:s' => \$output_path);
open my $lwlocknames, '<', $ARGV[0] or die; 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. # Include PID in suffix in case parallel make runs this multiple times.
my $htmp = "$output_path/lwlocknames.h.tmp$$"; my $htmp = "$output_path/lwlocknames.h.tmp$$";
@ -30,6 +31,40 @@ print $c $autogen, "\n";
print $c "const char *const IndividualLWLockNames[] = {"; 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>) while (<$lwlocknames>)
{ {
chomp; chomp;
@ -50,6 +85,15 @@ while (<$lwlocknames>)
die "lwlocknames.txt not in order" if $lockidx < $lastlockidx; die "lwlocknames.txt not in order" if $lockidx < $lastlockidx;
die "lwlocknames.txt has duplicates" 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) while ($lastlockidx < $lockidx - 1)
{ {
++$lastlockidx; ++$lastlockidx;
@ -63,6 +107,11 @@ while (<$lwlocknames>)
print $h "#define $lockname (&MainLWLockArray[$lockidx].lock)\n"; 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"; printf $c "\n};\n";
print $h "\n"; print $h "\n";
printf $h "#define NUM_INDIVIDUAL_LWLOCKS %s\n", $lastlockidx + 1; printf $h "#define NUM_INDIVIDUAL_LWLOCKS %s\n", $lastlockidx + 1;

@ -276,6 +276,10 @@ Extension "Waiting in an extension."
# This class of wait events has its own set of C structure, so these are # This class of wait events has its own set of C structure, so these are
# only used for the documentation. # 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 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." WaitEventExtension "Waiting to read or update custom wait events information for extensions."
WALSummarizer "Waiting to read or update WAL summarization state." 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." XactBuffer "Waiting for I/O on a transaction status SLRU buffer."
CommitTsBuffer "Waiting for I/O on a commit timestamp SLRU buffer." CommitTsBuffer "Waiting for I/O on a commit timestamp SLRU buffer."
SubtransBuffer "Waiting for I/O on a sub-transaction SLRU buffer." SubtransBuffer "Waiting for I/O on a sub-transaction SLRU buffer."

@ -1,7 +1,9 @@
# Copyright (c) 2022-2024, PostgreSQL Global Development Group # Copyright (c) 2022-2024, PostgreSQL Global Development Group
lwlocknames = custom_target('lwlocknames', 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'], output: ['lwlocknames.h', 'lwlocknames.c'],
command: [ command: [
perl, files('../../backend/storage/lmgr/generate-lwlocknames.pl'), perl, files('../../backend/storage/lmgr/generate-lwlocknames.pl'),

Loading…
Cancel
Save