|
From: sfeam <sf...@us...> - 2018-10-15 03:35:18
|
On Sunday, 14 October 2018 18:25:31 Dima Kogan wrote:
> I just hit another bug in the same area; a more serious one this time.
>
> When I run gnuplot normally with 'pause mouse close', it blocks
> somewhere, and doesn't waste cycles while we're waiting. In my usage,
> however, I rarely run gnuplot directly. I almost always use either
> feedgnuplot (a shell frontend) or gnuplotlib (a plotting interface for
> numpy in python). At least in the latter case, the 'pause mouse close'
> works, but gnuplot spins instead of blocking, which wastes CPU
> resources.
>
> I'm attaching a tiny program in python that shows the issue. You should
> change the GNUPLOT_SRC_DIR definition in that program to point to your
> source tree. This test program
>
> - spawns gnuplot (as a child of the python)
> - asks it to plot something
> - "pause mouse close"
> - "print xxx"
> - reads gnuplot output until it sees "xxx". This is the most reliable
> way I've found to let programs talk to gnuplot. If you know of a
> better synchronization method, please tell me
>
> When I run this python program I see gnuplot repeatedly call usleep(10)
> in X11_waitforinput() in x11.trm. I haven't looked enough at this code
> path to understand what it's trying to accomplish. It feels like we
> should never be doing this: all waiting should happen in the select() or
> something like it.
It is on purpose, wisely chosen or not.
> I also don't understand why I'm hitting this code
> path in python, but not if I run gnuplot interactively ("gnuplot" and
> then type in the commands) and not if I run it as a script (put the
> "plot" and "pause mouse close" into tst.gp, and "gnuplot tst.gp").
This is explained in the comments at x11.trm:894
/* When taking input from the console, we are willing to wait here */
/* until the next character is typed. But if input is from a script */
/* we just want to check for hotkeys or mouse input and then leave */
/* again without waiting on stdin. */
When the input is from the console we can select on stdin and not spin.
But if input is from a pipe this will always return immediately unless the
other end of the pipe does something clever to interlock operations.
That would make "pause mouse" useless. So if the input is from a pipe then
it spins at line 991 as you found. If you find the cost of spinning too
severe you could bump the usleep to a higher value:
%%%%%
diff --git a/term/x11.trm b/term/x11.trm
index 11556f1..364d4b4 100644
--- a/term/x11.trm
+++ b/term/x11.trm
@@ -988,7 +988,7 @@ AGAIN:
/* Same sort of thing if we are specifically waiting for mouse input. */
if (paused_for_mouse) {
#ifdef HAVE_USLEEP
- usleep(10);
+ usleep(10000);
#endif
goto AGAIN;
}
%%%%%
As shown by "top" on my desktop machine that reduces the cost of spinning
from about 10% cpu to <1% cpu.
The downside is that this adds a 10msec delay in response to keystrokes.
That may well be a good trade-off. Or we could make the test more complicated
and use the shorter sleep for actual keystrokes (pause mouse key) and the
longer sleep when waiting for a close event (pause mouse close).
Let me know if that works for you.
Or maybe the whole loop can be written more cleverly so that the select
isn't useless when a pipe is involved.
Ethan
|