1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-02 11:44:50 +03:00

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
This commit is contained in:
Nathan Bossart 2024-01-09 11:05:19 -06:00
parent a7be2a6c26
commit 5b1b9bce84
5 changed files with 67 additions and 4 deletions

View File

@ -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

View File

@ -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

View File

@ -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;

View 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 # 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."

View File

@ -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'),