Rework lwlocknames.txt to become lwlocklist.h

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 74a7306310, 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
This commit is contained in:
Alvaro Herrera 2024-03-20 11:46:11 +01:00
parent e5da0fe3c2
commit da952b415f
No known key found for this signature in database
GPG Key ID: 1C20ACB9D5C564AE
12 changed files with 136 additions and 125 deletions

View File

@ -110,8 +110,8 @@ $(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 utils/activity/wait_event_names.txt 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 lwlocknames.c $(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 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 $(MAKE) -C utils/activity wait_event_types.h pgstat_wait_event.c wait_event_funcs_data.c

View File

@ -1,3 +1,2 @@
/lwlocknames.c
/lwlocknames.h /lwlocknames.h
/s_lock_test /s_lock_test

View File

@ -18,7 +18,6 @@ OBJS = \
lmgr.o \ lmgr.o \
lock.o \ lock.o \
lwlock.o \ lwlock.o \
lwlocknames.o \
predicate.o \ predicate.o \
proc.o \ proc.o \
s_lock.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 \ $(TASPATH) -L $(top_builddir)/src/common -lpgcommon \
-L $(top_builddir)/src/port -lpgport -lm -o s_lock_test -L $(top_builddir)/src/port -lpgport -lm -o s_lock_test
# see notes in src/backend/parser/Makefile lwlocknames.h: ../../../include/storage/lwlocklist.h ../../utils/activity/wait_event_names.txt generate-lwlocknames.pl
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
$(PERL) $(srcdir)/generate-lwlocknames.pl $^ $(PERL) $(srcdir)/generate-lwlocknames.pl $^
check: s_lock_test check: s_lock_test
@ -47,4 +42,4 @@ check: s_lock_test
clean: clean:
rm -f s_lock_test rm -f s_lock_test
rm -f lwlocknames.h lwlocknames.c rm -f lwlocknames.h

View File

@ -1,6 +1,6 @@
#!/usr/bin/perl #!/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 # Copyright (c) 2000-2024, PostgreSQL Global Development Group
use strict; use strict;
@ -14,26 +14,22 @@ my $continue = "\n";
GetOptions('outdir:s' => \$output_path); 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; 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$$";
my $ctmp = "$output_path/lwlocknames.c.tmp$$";
open my $h, '>', $htmp or die "Could not open $htmp: $!"; open my $h, '>', $htmp or die "Could not open $htmp: $!";
open my $c, '>', $ctmp or die "Could not open $ctmp: $!";
my $autogen = 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 $autogen;
print $h "/* there is deliberately not an #ifndef LWLOCKNAMES_H here */\n\n"; 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 # 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 @wait_event_lwlocks;
my $record_lwlocks = 0; my $record_lwlocks = 0;
@ -61,66 +57,70 @@ while (<$wait_event_names>)
# Record the LWLock. # Record the LWLock.
(my $waiteventname, my $waitevendocsentence) = split(/\t/, $_); (my $waiteventname, my $waitevendocsentence) = split(/\t/, $_);
push(@wait_event_lwlocks, $waiteventname . "Lock"); push(@wait_event_lwlocks, $waiteventname);
} }
my $in_comment = 0;
my $i = 0; my $i = 0;
while (<$lwlocknames>) while (<$lwlocklist>)
{ {
chomp; chomp;
# Skip comments # Skip single-line C comments and empty lines
next if /^#/; next if m{^\s*/\*.*\*/$};
next if /^\s*$/; next if /^\s*$/;
die "unable to parse lwlocknames.txt" # skip multiline C comments
unless /^(\w+)\s+(\d+)$/; 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; (my $lockidx, my $lockname) = ($1, $2);
$trimmedlockname =~ s/Lock$//;
die "lock names must end with 'Lock'" if $trimmedlockname eq $lockname;
die "lwlocknames.txt not in order" if $lockidx < $lastlockidx; die "lwlocklist.h not in order" if $lockidx < $lastlockidx;
die "lwlocknames.txt has duplicates" 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" . "wait_event_names.txt"
if $i >= scalar @wait_event_lwlocks; if $i >= scalar @wait_event_lwlocks;
die "lists of predefined LWLocks do not match (first mismatch at " die "lists of predefined LWLocks do not match (first mismatch at "
. "$wait_event_lwlocks[$i] in wait_event_names.txt and $lockname in " . "$wait_event_lwlocks[$i] in wait_event_names.txt and $lockname in "
. "lwlocknames.txt)" . "lwlocklist.h)"
if $wait_event_lwlocks[$i] ne $lockname; if $wait_event_lwlocks[$i] ne $lockname;
$i++; $i++;
while ($lastlockidx < $lockidx - 1) while ($lastlockidx < $lockidx - 1)
{ {
++$lastlockidx; ++$lastlockidx;
printf $c "%s \"<unassigned:%d>\"", $continue, $lastlockidx;
$continue = ",\n"; $continue = ",\n";
} }
printf $c "%s \"%s\"", $continue, $trimmedlockname;
$lastlockidx = $lockidx; $lastlockidx = $lockidx;
$continue = ",\n"; $continue = ",\n";
print $h "#define $lockname (&MainLWLockArray[$lockidx].lock)\n"; print $h "#define ${lockname}Lock (&MainLWLockArray[$lockidx].lock)\n";
} }
die die
"$wait_event_lwlocks[$i] defined in wait_event_names.txt but missing from " "$wait_event_lwlocks[$i] defined in wait_event_names.txt but missing from "
. "lwlocknames.txt" . "lwlocklist.h"
if $i < scalar @wait_event_lwlocks; if $i < scalar @wait_event_lwlocks;
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;
close $h; close $h;
close $c;
rename($htmp, "$output_path/lwlocknames.h") rename($htmp, "$output_path/lwlocknames.h")
|| die "rename: $htmp to $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;

View File

@ -112,8 +112,8 @@ StaticAssertDecl(LW_VAL_EXCLUSIVE > (uint32) MAX_BACKENDS,
* There are three sorts of LWLock "tranches": * There are three sorts of LWLock "tranches":
* *
* 1. The individually-named locks defined in lwlocknames.h each have their * 1. The individually-named locks defined in lwlocknames.h each have their
* own tranche. The names of these tranches appear in IndividualLWLockNames[] * own tranche. We absorb the names of these tranches from there into
* in lwlocknames.c. * BuiltinTrancheNames here.
* *
* 2. There are some predefined tranches for built-in groups of locks. * 2. There are some predefined tranches for built-in groups of locks.
* These are listed in enum BuiltinTrancheIds in lwlock.h, and their names * 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 * 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. * ... 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[] = { 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_XACT_BUFFER] = "XactBuffer",
[LWTRANCHE_COMMITTS_BUFFER] = "CommitTsBuffer", [LWTRANCHE_COMMITTS_BUFFER] = "CommitTsBuffer",
[LWTRANCHE_SUBTRANS_BUFFER] = "SubtransBuffer", [LWTRANCHE_SUBTRANS_BUFFER] = "SubtransBuffer",
@ -742,11 +743,7 @@ LWLockReportWaitEnd(void)
static const char * static const char *
GetLWTrancheName(uint16 trancheId) GetLWTrancheName(uint16 trancheId)
{ {
/* Individual LWLock? */ /* Built-in tranche or individual LWLock? */
if (trancheId < NUM_INDIVIDUAL_LWLOCKS)
return IndividualLWLockNames[trancheId];
/* Built-in tranche? */
if (trancheId < LWTRANCHE_FIRST_USER_DEFINED) if (trancheId < LWTRANCHE_FIRST_USER_DEFINED)
return BuiltinTrancheNames[trancheId]; return BuiltinTrancheNames[trancheId];

View File

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

View File

@ -11,5 +11,3 @@ backend_sources += files(
's_lock.c', 's_lock.c',
'spin.c', 'spin.c',
) )
generated_backend_sources += lwlocknames[1]

View 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 # 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 # 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 # listed in the top section of locks and must be listed in the same order as in
# lwlocknames.txt. # lwlocklist.h.
# #
Section: ClassName - WaitEventLWLock 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) # 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 # 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." XactBuffer "Waiting for I/O on a transaction status SLRU buffer."

View File

@ -19,6 +19,7 @@
#endif #endif
#include "port/atomics.h" #include "port/atomics.h"
#include "storage/lwlocknames.h"
#include "storage/proclist_types.h" #include "storage/proclist_types.h"
struct PGPROC; struct PGPROC;
@ -82,9 +83,6 @@ typedef struct NamedLWLockTranche
extern PGDLLIMPORT NamedLWLockTranche *NamedLWLockTrancheArray; extern PGDLLIMPORT NamedLWLockTranche *NamedLWLockTrancheArray;
extern PGDLLIMPORT int NamedLWLockTrancheRequests; 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 * 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 * here, but we need them to figure out offsets within MainLWLockArray, and

View File

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

View File

@ -1,10 +1,10 @@
# Copyright (c) 2022-2024, PostgreSQL Global Development Group # Copyright (c) 2022-2024, PostgreSQL Global Development Group
lwlocknames = custom_target('lwlocknames', lwlocknames_h = custom_target('lwlocknames_h',
input: files( input: files(
'../../backend/storage/lmgr/lwlocknames.txt', '../../include/storage/lwlocklist.h',
'../../backend/utils/activity/wait_event_names.txt'), '../../backend/utils/activity/wait_event_names.txt'),
output: ['lwlocknames.h', 'lwlocknames.c'], output: ['lwlocknames.h'],
command: [ command: [
perl, files('../../backend/storage/lmgr/generate-lwlocknames.pl'), perl, files('../../backend/storage/lmgr/generate-lwlocknames.pl'),
'-o', '@OUTDIR@', '-o', '@OUTDIR@',
@ -12,12 +12,10 @@ lwlocknames = custom_target('lwlocknames',
], ],
build_by_default: true, build_by_default: true,
install: 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 generated_backend_headers += lwlocknames_h
# autoconf generates the file there, ensure we get a conflict # 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']}

View File

@ -133,6 +133,7 @@ do
test "$f" = src/interfaces/ecpg/preproc/c_kwlist.h && continue test "$f" = src/interfaces/ecpg/preproc/c_kwlist.h && continue
test "$f" = src/interfaces/ecpg/preproc/ecpg_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/regex/regerrs.h && continue
test "$f" = src/include/storage/lwlocklist.h && continue
test "$f" = src/include/tcop/cmdtaglist.h && continue test "$f" = src/include/tcop/cmdtaglist.h && continue
test "$f" = src/pl/plpgsql/src/plerrcodes.h && continue test "$f" = src/pl/plpgsql/src/plerrcodes.h && continue
test "$f" = src/pl/plpython/spiexceptions.h && continue test "$f" = src/pl/plpython/spiexceptions.h && continue