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
$(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

View File

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

View 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

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

View 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];

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',
'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
# 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."

View 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

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
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']}

View File

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