Re: Improve heavyweight locks instead of building new lock managers?
От | Andres Freund |
---|---|
Тема | Re: Improve heavyweight locks instead of building new lock managers? |
Дата | |
Msg-id | 20200323222350.vjc4t36rb34fz4ie@alap3.anarazel.de обсуждение исходный текст |
Ответ на | Re: Improve heavyweight locks instead of building new lock managers? (Thomas Munro <thomas.munro@gmail.com>) |
Список | pgsql-hackers |
Hi, On 2020-02-21 12:40:06 +1300, Thomas Munro wrote: > On Thu, Feb 20, 2020 at 5:14 PM Andres Freund <andres@anarazel.de> wrote: > > 16 files changed, 569 insertions(+), 1053 deletions(-) > > Nice! Thanks! > Some comments on 0001, 0003, 0004: > > > Subject: [PATCH v1 1/6] Add additional prev/next & detached node functions to > > +extern void dlist_check(const dlist_head *head); > +extern void slist_check(const slist_head *head); > > I approve of the incidental constification in this patch. It was just necessary fallout :) > +/* > + * Like dlist_delete(), but also sets next/prev to NULL to signal not being in > + * list. > + */ > +static inline void > +dlist_delete_thoroughly(dlist_node *node) > +{ > + node->prev->next = node->next; > + node->next->prev = node->prev; > + node->next = NULL; > + node->prev = NULL; > +} > > Instead of introducing this strange terminology, why not just have the > callers do ... > > dlist_delete(node); > dlist_node_init(node); There's quite a few callers in predicate.c - I actually did that first. > ..., or perhaps supply dlist_delete_and_reinit(node) that does exactly > that? That is, reuse the code and terminology. Yea, that's might be better, but see paragraph below. I quite dislike adding any "empty node" state. > +/* > + * Check if node is detached. A node is only detached if it either has been > + * initialized with dlist_init_node(), or deleted with > + * dlist_delete_thoroughly(). > + */ > +static inline bool > +dlist_node_is_detached(const dlist_node *node) > +{ > + Assert((node->next == NULL && node->prev == NULL) || > + (node->next != NULL && node->prev != NULL)); > + > + return node->next == NULL; > +} > > How about dlist_node_is_linked()? I don't like introducing random new > verbs when we already have 'linked' in various places, and these > things are, y'know, linked lists. Well, but that doesn't signal that you can't just delete and have dlist_node_is_linked() work. I *want* it to sound "different". We could of course make delete always do this, but I don't want to add that overhead unnecessarily. > > Subject: [PATCH v1 4/6] Use dlists for predicate locking. > > + dlist_foreach(iter, &unconstify(SERIALIZABLEXACT *, reader)->outConflicts) > > Yuck... It doesn't seem *that* bad to me, at least signals properly what we're doing, and only does so in one place. > I suppose you could do this: > > - dlist_foreach(iter, &unconstify(SERIALIZABLEXACT *, reader)->outConflicts) > + dlist_foreach_const(iter, &reader->outConflicts) We'd need a different iterator type too, I think? Because the iterator itself can't be constant, but we'd want the elements themselves be pointers to constants. const just isn't a very granular thing in C :(. > ... given: > > +/* Variant for when you have a pointer to const dlist_head. */ > +#define dlist_foreach_const(iter, lhead) \ > + for (AssertVariableIsOfTypeMacro(iter, dlist_iter), \ > + AssertVariableIsOfTypeMacro(lhead, const dlist_head *), \ > + (iter).end = (dlist_node *) &(lhead)->head, \ > + (iter).cur = (iter).end->next ? (iter).end->next : (iter).end; \ > + (iter).cur != (iter).end; \ > + (iter).cur = (iter).cur->next) > + > > ... or find a way to make dlist_foreach() handle that itself, which > seems pretty reasonable given its remit to traverse lists without > modifying them, though perhaps that would require a different iterator > type... I was trying that first, but I don't easily see how we can do so. Iterating over a non-constant list with dlist_foreach obviously still allows to to manipulate the list members. Thus dlist_iter.cur can't be a 'pointer to const'. Whereas that's arguably what'd be needed for a correct dlist_foreach() of a constant list? We could just accept const pointers for dlist_foreach(), but then we'd *always* accept them, and we'd thus unconditionally have iter.cur as non-const. Would that be better? > Otherwise looks OK to me and passes various tests I threw at it Thanks! Greetings, Andres Freund
В списке pgsql-hackers по дате отправления: