> >> I was imagining putting the array in one big DSA allocation instead of
> >> carting around a pointer for each tranche name. (Sorry, I realize I am
> >> hand-waving over some of the details.)
> >
> > I understood it like this. Here is a sketch:
> >
> > ```
> > dsa_pointer p;
> >
> > dsa = dsa_create(....)
> >
> > p = dsa_allocate(dsa, LWLockTranchesInitialSize());
> > tranche_names = (char **) dsa_get_address(dsa, p);
> > tranche_names[0] = "my tranche";
> > tranche_names[1] = "my tranche";
> > ```
> >
> > We will need to track the size and resize if needed.
> >
> > Is this what you mean, from a high level?
>
> Yes, that's roughly what I had in mind. We might need to employ some
> tricks to avoid a limit on tranche name length, but maybe that's not worth
> the energy.
After spending some time looking at this, I don't think it's a good idea to
do as mentioned above, since it's unclear when to resize the dsa pointer.
It's better to have a single dsa pointer that holds a list of dsa
pointers, each tracking a tranche name. We can also track the size of this
list and grow it when needed. Essentially we should only be manipulating
a DSA area via dsa_pointers.
Attached is what I have in mind, if we want to avoid using dshash.
This patch initializes a DSA with create_in_place at startup ( similar to what
we do for pgstat, see pgstat_shmem.c) , and provides
a routine to append a tranche name to the list, as well as a routine to
look up a tranche name by index. The index is the tranche ID offset by
LWTRANCHE_FIRST_USER_DEFINED.
Additionally, this patch removes the step in [0] to call LWLockRegisterTranche.
Instead, LWLockNewTrancheId now takes a tranche_name and returns the
tranche ID. This new API is what we discussed earlier, and I agree with it,
as it simplifies the workflow. LWLockRegisterTranche is still kept, but it's
a private routine.
To support the above, LWLockTrancheNames is now a struct that tracks both a
local list of tranche names (populated during postmaster startup) and
pointers to shared memory, for tranche names registered after postmaster.
GetLWTrancheName now first checks BuiltinTrancheNames, then the local
list in LWLockTrancheNames, and finally the shared memory. This allows
tranche names registered after postmaster startup to be visible to all
backends.
Unlike the local list of tranche names, appending to and searching the
shared memory list requires an LWLock; in exclusive mode to append, and
shared mode to search.
--
Sami
[0] https://www.postgresql.org/docs/current/xfunc-c.html#XFUNC-ADDIN-LWLOCKS-AFTER-STARTUP