Thread: TODO-item: Add sleep() function, remove from regress.c

TODO-item: Add sleep() function, remove from regress.c

From
Joachim Wieland
Date:
I propose the appended patch for the todo item:

* Add sleep() function, remove from regress.c

The patch also removes do_sleep() from the regression and substitues this
with the call to the new function.

I'd personally prefer to call the function pg_sleep(), but since it is
called sleep() on the TODO list and in previous discussions, I kept the
name. The internal function is called pg_sleep() however.

There was a discussion about this item in August of last year

http://archives.postgresql.org/pgsql-hackers/2005-08/msg00633.php

A few people liked the idea, Tom Lane pointed out that it's bad to have a
sleeping backend that can hold locks for a long time. Other developers
answered that this should just be documented since the user can do that
anyways very easily if he is allowed to create functions in one of the
traditional scripting languages or with busy waiting also in plpgsql.

Finally the item got added to the TODO list and nobody objected.

In the mysqlcompat project there is a sleep function that does busy waiting,
this function could profit from a sleep() function in the backend.

To the docs I introduced a new paragraph such that it is easy to find this
function and labeled the note about the locks with the "warning" tag.


Tom, can you live with that?

Other Comments?


Joachim


Attachment

Re: TODO-item: Add sleep() function, remove from regress.c

From
Tom Lane
Date:
Joachim Wieland <joe@mcknight.de> writes:
> I'd personally prefer to call the function pg_sleep(), but since it is
> called sleep() on the TODO list and in previous discussions, I kept the
> name. The internal function is called pg_sleep() however.

pg_sleep seems like a better idea to me too.

Why is the function defined to take numeric rather than float8?
float8 is a whole lot easier to work with internally.  (Performance
doesn't seem like an issue here, but length and readability of the code
are worth worrying about.)  Further, you could avoid assuming that the
machine has working int64 arithmetic, which is an assumption I still
think we should avoid everywhere that it's not absolutely essential.

The proposed regression test seems unacceptably fragile, as well as
rather pointless.

            regards, tom lane

Re: TODO-item: Add sleep() function, remove from regress.c

From
Tom Lane
Date:
BTW, a serious problem with just passing it off to pg_usleep like that
is that the sleep can't be aborted by a cancel request; doesn't seem
like a good idea to me.  I'd suggest writing a loop that sleeps for at
most a second at a time, with a CHECK_FOR_INTERRUPTS() before each
sleep.  This would also allow you to eliminate the arbitrary restriction
on length of sleep.

            regards, tom lane

Re: TODO-item: Add sleep() function, remove from regress.c

From
Joachim Wieland
Date:
On Mon, Jan 09, 2006 at 08:50:36PM -0500, Tom Lane wrote:
> pg_sleep seems like a better idea to me too.

ok, renamed again.

> Why is the function defined to take numeric rather than float8?
> float8 is a whole lot easier to work with internally.

ok, changed.

> The proposed regression test seems unacceptably fragile, as well as
> rather pointless.

Why is it fragile? Which other regression test do you suggest? Or should it
go without one?


On Mon, Jan 09, 2006 at 08:54:49PM -0500, Tom Lane wrote:
> BTW, a serious problem with just passing it off to pg_usleep like that
> is that the sleep can't be aborted by a cancel request

No, cancelling the sleep works (at least for Unix). Isn't cancelling
implemented via a signal that interrupts select() ?

Anyway, I've changed it, removing the ~2000s limit is a good point.


I append a new version with the regression test ripped out.


Joachim


Attachment

Re: TODO-item: Add sleep() function, remove from regress.c

From
Tom Lane
Date:
Joachim Wieland <joe@mcknight.de> writes:
> On Mon, Jan 09, 2006 at 08:50:36PM -0500, Tom Lane wrote:
>> The proposed regression test seems unacceptably fragile, as well as
>> rather pointless.

> Why is it fragile?

As your own comment pointed out, the test would "fail" on a heavily
loaded system, due to sleeping too long.  I do not see the need for
such a test anyway --- the stats regression test will exercise the
code sufficiently.

>> BTW, a serious problem with just passing it off to pg_usleep like that
>> is that the sleep can't be aborted by a cancel request

> No, cancelling the sleep works (at least for Unix). Isn't cancelling
> implemented via a signal that interrupts select() ?

On some systems the signal will interrupt select.  On some, not.
Note the coding in bgwriter.c's main loop for instance.

            regards, tom lane

Re: TODO-item: Add sleep() function, remove from regress.c

From
"Jim C. Nasby"
Date:
On Tue, Jan 10, 2006 at 11:31:13AM +0100, Joachim Wieland wrote:
> No, cancelling the sleep works (at least for Unix). Isn't cancelling
> implemented via a signal that interrupts select() ?
>
> Anyway, I've changed it, removing the ~2000s limit is a good point.
> +     while (secs > 1.0)
> +     {
> +         pg_usleep(1000000);
> +         CHECK_FOR_INTERRUPTS();
> +         secs -= 1.0;
> +     }

Won't this result in a call to pg_sleep with a long sleep time ending up
sleeping noticeably longer than requested?
--
Jim C. Nasby, Sr. Engineering Consultant      jnasby@pervasive.com
Pervasive Software      http://pervasive.com    work: 512-231-6117
vcard: http://jim.nasby.net/pervasive.vcf       cell: 512-569-9461

Re: TODO-item: Add sleep() function, remove from regress.c

From
Andrew Dunstan
Date:

Jim C. Nasby wrote:

>On Tue, Jan 10, 2006 at 11:31:13AM +0100, Joachim Wieland wrote:
>
>
>>No, cancelling the sleep works (at least for Unix). Isn't cancelling
>>implemented via a signal that interrupts select() ?
>>
>>Anyway, I've changed it, removing the ~2000s limit is a good point.
>>+     while (secs > 1.0)
>>+     {
>>+         pg_usleep(1000000);
>>+         CHECK_FOR_INTERRUPTS();
>>+         secs -= 1.0;
>>+     }
>>
>>
>
>Won't this result in a call to pg_sleep with a long sleep time ending up
>sleeping noticeably longer than requested?
>
>

Looks like it to me.

Instead of using a counter it might be better to set a target end time
and check that against the value returned from time() or gettimeofday().

cheers

andrew

Re: TODO-item: Add sleep() function, remove from regress.c

From
Tom Lane
Date:
Andrew Dunstan <andrew@dunslane.net> writes:
> Jim C. Nasby wrote:
>> Won't this result in a call to pg_sleep with a long sleep time ending up
>> sleeping noticeably longer than requested?

> Looks like it to me.

Something on the order of 1% longer, hm?  (1 extra clock tick per second,
probably.)  Can't get excited about it --- *all* implementations of sleep
say that the time is minimum not exact.

            regards, tom lane

Re: TODO-item: Add sleep() function, remove from regress.c

From
"Andrew Dunstan"
Date:
Tom Lane said:
> Andrew Dunstan <andrew@dunslane.net> writes:
>> Jim C. Nasby wrote:
>>> Won't this result in a call to pg_sleep with a long sleep time ending
>>> up sleeping noticeably longer than requested?
>
>> Looks like it to me.
>
> Something on the order of 1% longer, hm?  (1 extra clock tick per
> second, probably.)  Can't get excited about it --- *all*
> implementations of sleep say that the time is minimum not exact.
>

Well yes, although it's cumulative. I guess I'm not excited for a different
reason - I'm having trouble imagining much of a use case.

cheers

andrew



Re: TODO-item: Add sleep() function, remove from regress.c

From
Tom Lane
Date:
Joachim Wieland <joe@mcknight.de> writes:
> I append a new version with the regression test ripped out.

Applied with revisions.  I concluded that the idea of computing the
end-time in advance had merit, so I changed the code to do it that way.
Aside from not allowing extra delay to accumulate in a multiple-second
wait, this guarantees that we cannot wait *less* than the requested
time, which is a hazard if the system has interruptible select().

Other minor comments: if you declare the function strict it is not
necessary to check for null inputs, and you were doing the float-to-int
conversion the hard way.

            regards, tom lane