Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Tom Lane
Andres Freund  writes:
> The first attached patch adds slist_delete_current(), updates the
> comments addressing your points and converts the bgworker code to pass
> the iterator around (it's more efficient which might actually matter
> with a few hundred bgworkers).

Applied with fixes.  The slist_delete_current() logic wouldn't actually
work for deleting multiple adjacent list elements, because the foreach
macro would advance prev to point at the just-deleted element.  Compare
the places where we use list_delete_cell() in a loop --- we're careful
to advance prev only when we *don't* delete the current element.
I dealt with that by making slist_delete_current() back up the
iterator's "cur" pointer to equal "prev", so that the loop macro's next
copying of "cur" to "prev" is a no-op.  This means callers can't rely on
"cur" anymore after the deletion, but in typical usage they'd have
computed a pointer to their struct already so this shouldn't be a
problem.  Another fine point is you can't use both slist_delete and
slist_delete_current within the same loop, since the former wouldn't
apply this correction.

Also, I fixed the slist_foreach_modify macro to not doubly evaluate
its lhead argument, since I think we agreed that was a bad idea,
and did some more work on the comments.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Andres Freund
> Andres Freund  writes:
> > The first attached patch adds slist_delete_current(), updates the
> > comments addressing your points and converts the bgworker code to pass
> > the iterator around (it's more efficient which might actually matter
> > with a few hundred bgworkers).
> > I found the added newlines in slist_foreach_modify useful, but maybe they
> > should be removed again.
> 
> > I think this should be included in 9.3 once reviewed.
> 
> Agreed; since we have not shipped ilist.h in a release yet, the benefits
> of having it behave the same in all branches should outweigh any pain
> from changing this post-beta.

Especially as it shouldn't break any existing working code since the old
API is still there. Obviously it breaks the ABI, but ...

On 2013-07-24 14:29:42 -0400, Tom Lane wrote:
> > The second patch adds a regression test for background workers via
> > worker_spi which I used to test slist_delete_current() addition. It's not 
> > 100% as
> > it, but I thought it worthwile to post it anyway
> 
> Hm.  I'll review and commit the ilist changes, but Alvaro or somebody
> should decide if such a test is sensible.  I'd be a bit worried about
> it in a "make installcheck" context ...

I've disabled installcheck for that reason. Is there any way to override
a makefile target in gnu make without a warning?

If we want coverage for statically registered workers - which seems like
a good idea, we need our own postgresql.conf stanza and thus a manual
pg_regress invocation anyway. Which should fix that error.

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Tom Lane
Andres Freund  writes:
> The first attached patch adds slist_delete_current(), updates the
> comments addressing your points and converts the bgworker code to pass
> the iterator around (it's more efficient which might actually matter
> with a few hundred bgworkers).
> I found the added newlines in slist_foreach_modify useful, but maybe they
> should be removed again.

> I think this should be included in 9.3 once reviewed.

Agreed; since we have not shipped ilist.h in a release yet, the benefits
of having it behave the same in all branches should outweigh any pain
from changing this post-beta.

> The second patch adds a regression test for background workers via
> worker_spi which I used to test slist_delete_current() addition. It's not 
> 100% as
> it, but I thought it worthwile to post it anyway

Hm.  I'll review and commit the ilist changes, but Alvaro or somebody
should decide if such a test is sensible.  I'd be a bit worried about
it in a "make installcheck" context ...

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Andres Freund
Hi,

On 2013-07-24 11:49:20 -0400, Tom Lane wrote:
> Andres Freund  writes:
> > This will require another member variable in slist_mutable_iter which
> > obviously will need to be maintained, but that seems fine to me since it
> > will reduce the cost of actually deleting noticeably.
> 
> I think that's all right.  Conceivably we could introduce two forms of
> iterator depending on whether you want to delete or not, but that seems
> like overkill to me.

Agreed. Especially as you point out there's no real point to
mutable_iter as committed.

> In fact, now that I think about it, the distinction between slist_iter
> and slist_mutable_iter is really misstated in the comments, isn't it?
> The *only* action on the list that's unsafe with an active slist_iter
> is to delete the current element (and then continue iterating).
> If the value of slist_mutable_iter is to support deletion of the current
> element, then it seems obvious that it should support doing so
> efficiently, ie it should carry both prev and next.  Also, if it's
> carrying both of those, then use of slist_mutable_iter really doesn't
> allow any action other than deleting the current element --- adding
> new nodes "ahead" of the current element isn't safe.

True. I think I mentally copy&pasted to much logic from the doubly
linked list case.

The first attached patch adds slist_delete_current(), updates the
comments addressing your points and converts the bgworker code to pass
the iterator around (it's more efficient which might actually matter
with a few hundred bgworkers).
I found the added newlines in slist_foreach_modify useful, but maybe they
should be removed again.

I think this should be included in 9.3 once reviewed.

The second patch adds a regression test for background workers via
worker_spi which I used to test slist_delete_current() addition. It's not 100% 
as
it, but I thought it worthwile to post it anyway
a) only tests dynamically registered workers, it should start it's own
   regression test starting some bgworkers statically
b) disables installcheck harshly causing a warning from make:
/home/andres/src/postgresql/src/makefiles/pgxs.mk:297: warning: ignoring old 
commands for target `installcheck'
Manually defining a pg_regress in 'check:' should fix it probably
because that part of pgxs.mk is dependant on REGRESS = being set.
c) it only tests BGW_NEVER_RESTART

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
>From 0dfa542f457ebd71640830a993e3a428720b4179 Mon Sep 17 00:00:00 2001
From: Andres Freund 
Date: Wed, 24 Jul 2013 19:34:10 +0200
Subject: [PATCH 1/2] Add slist_delete_current()

---
 src/backend/lib/ilist.c |  2 +-
 src/backend/postmaster/bgworker.c   |  5 -
 src/backend/postmaster/postmaster.c |  4 ++--
 src/include/lib/ilist.h | 32 +
 src/include/postmaster/bgworker_internals.h |  2 +-
 5 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/src/backend/lib/ilist.c b/src/backend/lib/ilist.c
index 957a118..dddb6eb 100644
--- a/src/backend/lib/ilist.c
+++ b/src/backend/lib/ilist.c
@@ -28,7 +28,7 @@
  *
  * It is not allowed to delete a 'node' which is is not in the list 'head'
  *
- * Caution: this is O(n)
+ * Caution: this is O(n), use slist_delete_current() while iterating.
  */
 void
 slist_delete(slist_head *head, slist_node *node)
diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c
index ada24e9..9967b69 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -272,10 +272,13 @@ BackgroundWorkerStateChange(void)
  * the postmaster.
  */
 void
-ForgetBackgroundWorker(RegisteredBgWorker *rw)
+ForgetBackgroundWorker(slist_mutable_iter *cur)
 {
+	RegisteredBgWorker *rw;
 	BackgroundWorkerSlot *slot;
 
+	rw = slist_container(RegisteredBgWorker, rw_lnode, cur->cur);
+
 	Assert(rw->rw_shmem_slot < max_worker_processes);
 	slot = &BackgroundWorkerData->slot[rw->rw_shmem_slot];
 	slot->in_use = false;
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index b6b8111..0342be7 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -1452,7 +1452,7 @@ DetermineSleepTime(struct timeval * timeout)
 
 			if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
 			{
-ForgetBackgroundWorker(rw);
+ForgetBackgroundWorker(&siter);
 continue;
 			}
 
@@ -5643,7 +5643,7 @@ StartOneBackgroundWorker(void)
 		{
 			if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
 			{
-ForgetBackgroundWorker(rw);
+ForgetBackgroundWorker(&iter);
 continue;
 			}
 
diff --git a/src/include/lib/ilist.h b/src/include/lib/ilist.h
index 73f4115..f8f0458 100644
--- a/src/include/lib/ilist.h
+++ b/src/include/lib/ilist.h
@@ -211,7 +211,9 @@ typedef struct slist_head
  * Used as state in slist_foreach

Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Alvaro Herrera
Andres Freund wrote:
> On 2013-07-24 11:53:39 -0400, Alvaro Herrera wrote:
> > Andres Freund wrote:

> > Amusingly, this will mean ForgetBackgroundWorker() will need to have a
> > slist_mutable_iter * argument if it wants to use the new function ...
> 
> The only alternative I see would be to pass both the prev, and the cur
> elements which seems to be less expressive from my POV.
> I am open to other suggestions?

In the grand scheme of things, I think it's fine.

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Andres Freund
On 2013-07-24 11:53:39 -0400, Alvaro Herrera wrote:
> Andres Freund wrote:
> > On 2013-07-24 11:26:00 -0400, Tom Lane wrote:
> 
> > > So I'm going to end up hand-implementing the same kind of manipulation
> > > we frequently use with traditional Lists, namely keep a second variable
> > > that's the preceding list element (not the next one) so I can unlink and
> > > delete the target element when I find it.  ilist.h is not offering me
> > > any useful support at all for this scenario.  Seems like we're missing
> > > a bet here.
> > 
> > Hm. Yes. This should be added. I didn't need it so far, but I definitely
> > can see usecases.
> > 
> > slist_delete_current(slist_mutable_iter *)?
> > 
> > I am willing to cough up a patch if you want.
> > 
> > This will require another member variable in slist_mutable_iter which
> > obviously will need to be maintained, but that seems fine to me since it
> > will reduce the cost of actually deleting noticeably.
> 
> Amusingly, this will mean ForgetBackgroundWorker() will need to have a
> slist_mutable_iter * argument if it wants to use the new function ...

The only alternative I see would be to pass both the prev, and the cur
elements which seems to be less expressive from my POV.
I am open to other suggestions?

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Alvaro Herrera
Andres Freund wrote:
> On 2013-07-24 11:26:00 -0400, Tom Lane wrote:

> > So I'm going to end up hand-implementing the same kind of manipulation
> > we frequently use with traditional Lists, namely keep a second variable
> > that's the preceding list element (not the next one) so I can unlink and
> > delete the target element when I find it.  ilist.h is not offering me
> > any useful support at all for this scenario.  Seems like we're missing
> > a bet here.
> 
> Hm. Yes. This should be added. I didn't need it so far, but I definitely
> can see usecases.
> 
> slist_delete_current(slist_mutable_iter *)?
> 
> I am willing to cough up a patch if you want.
> 
> This will require another member variable in slist_mutable_iter which
> obviously will need to be maintained, but that seems fine to me since it
> will reduce the cost of actually deleting noticeably.

Amusingly, this will mean ForgetBackgroundWorker() will need to have a
slist_mutable_iter * argument if it wants to use the new function ...

-- 
Álvaro Herrerahttp://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Tom Lane
Andres Freund  writes:
> On 2013-07-24 11:26:00 -0400, Tom Lane wrote:
>> So I'm going to end up hand-implementing the same kind of manipulation
>> we frequently use with traditional Lists, namely keep a second variable
>> that's the preceding list element (not the next one) so I can unlink and
>> delete the target element when I find it.  ilist.h is not offering me
>> any useful support at all for this scenario.  Seems like we're missing
>> a bet here.

> Hm. Yes. This should be added. I didn't need it so far, but I definitely
> can see usecases.
> slist_delete_current(slist_mutable_iter *)?
> I am willing to cough up a patch if you want.

Please.

> This will require another member variable in slist_mutable_iter which
> obviously will need to be maintained, but that seems fine to me since it
> will reduce the cost of actually deleting noticeably.

I think that's all right.  Conceivably we could introduce two forms of
iterator depending on whether you want to delete or not, but that seems
like overkill to me.

In fact, now that I think about it, the distinction between slist_iter
and slist_mutable_iter is really misstated in the comments, isn't it?
The *only* action on the list that's unsafe with an active slist_iter
is to delete the current element (and then continue iterating).
If the value of slist_mutable_iter is to support deletion of the current
element, then it seems obvious that it should support doing so
efficiently, ie it should carry both prev and next.  Also, if it's
carrying both of those, then use of slist_mutable_iter really doesn't
allow any action other than deleting the current element --- adding
new nodes "ahead" of the current element isn't safe.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


Re: [HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Andres Freund
On 2013-07-24 11:26:00 -0400, Tom Lane wrote:
> So I went off to implement the SPITupleTable tracking discussed in
> <6553.1374424...@sss.pgh.pa.us>, and thought it would be cool to
> use the slist infrastructure defined in lib/ilist.h rather than
> creating a separate List node for each SPITupleTable struct.
> However, I soon ran into a problem: there's no real support for
> "remove the current element of an slist while we're scanning it",
> which is really the only list manipulation I need.  The only way
> to remove an element is slist_delete(), which will iterate over
> the list *again* and thus create an O(N^2) penalty.  Or I could
> use a dlist, but two pointers per struct seem pretty silly.

> So I'm going to end up hand-implementing the same kind of manipulation
> we frequently use with traditional Lists, namely keep a second variable
> that's the preceding list element (not the next one) so I can unlink and
> delete the target element when I find it.  ilist.h is not offering me
> any useful support at all for this scenario.  Seems like we're missing
> a bet here.

Hm. Yes. This should be added. I didn't need it so far, but I definitely
can see usecases.

slist_delete_current(slist_mutable_iter *)?

I am willing to cough up a patch if you want.

This will require another member variable in slist_mutable_iter which
obviously will need to be maintained, but that seems fine to me since it
will reduce the cost of actually deleting noticeably.

Greetings,

Andres Freund

-- 
 Andres Freund http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers


[HACKERS] ilist.h is not useful as-is

2013-07-24 Thread Tom Lane
So I went off to implement the SPITupleTable tracking discussed in
<6553.1374424...@sss.pgh.pa.us>, and thought it would be cool to
use the slist infrastructure defined in lib/ilist.h rather than
creating a separate List node for each SPITupleTable struct.
However, I soon ran into a problem: there's no real support for
"remove the current element of an slist while we're scanning it",
which is really the only list manipulation I need.  The only way
to remove an element is slist_delete(), which will iterate over
the list *again* and thus create an O(N^2) penalty.  Or I could
use a dlist, but two pointers per struct seem pretty silly.

So I'm going to end up hand-implementing the same kind of manipulation
we frequently use with traditional Lists, namely keep a second variable
that's the preceding list element (not the next one) so I can unlink and
delete the target element when I find it.  ilist.h is not offering me
any useful support at all for this scenario.  Seems like we're missing
a bet here.

regards, tom lane


-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers