"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Mark Jamsek <mark@jamsek.com>
Subject:
Re: tog: 100% cpu usage after search in full-screen mode
To:
Mikhail <mp39590@gmail.com>
Cc:
gameoftrees@openbsd.org
Date:
Wed, 8 Feb 2023 17:57:00 +1100

Download raw body.

Thread
On 23-02-07 09:23PM, Mikhail wrote:
> I spent a little bit time on this, but wasn't able to get a clue:
> 
> run tog in got repo
> wait 10 secs
> <enter>
> F
> /whatever
> 
> look in 'top' how tog slowly starts eating whole CPU.

Nice find! Thanks, Mikhail :)

This is indeed a weird one! I think it's because we unset our 1s refresh
rate when entering view_search_start(), and because fast_refresh is now
0, we never meet that condition in view_input() to reset it back to 1s
again.

Whereas if we follow the recipe without waiting 10s, fast_refresh will
still be > 0 thus the 1s refresh rate will still be set in view_input().

> I dug it to view_loop, which starts cycling like crazy. Pressing 'q'
> while in full-screen cpu-eating mode makes tog back to normal cpu usage.
> 
> Inlined patch fixes the issue for me, but it's "monkey see - monkey do"
> kind of patch, can't propose it like a solution:

While the diff does indeed fix the problem, I don't think we want to
call halfdelay() every iteration. We could make it a global, but it's
only used in now two locations, so let's pass it as an argument instead.

diff /home/mark/src/got
commit - ec218e165dfd906f44ad491671127ca4b6979ed0
path + /home/mark/src/got
blob - a6351da680ffacc2f47bf1a42b494d77af0b4a3a
file + tog/tog.c
--- tog/tog.c
+++ tog/tog.c
@@ -1288,7 +1288,7 @@ view_search_start(struct tog_view *view)
 }
 
 static const struct got_error *
-view_search_start(struct tog_view *view)
+view_search_start(struct tog_view *view, int fast_refresh)
 {
 	const struct got_error *err = NULL;
 	struct tog_view *v = view;
@@ -1321,6 +1321,8 @@ view_search_start(struct tog_view *view)
 	cbreak();
 	noecho();
 	nodelay(v->window, TRUE);
+	if (!fast_refresh)
+		halfdelay(10);
 	if (ret == ERR)
 		return NULL;
 
@@ -1488,7 +1490,7 @@ view_input(struct tog_view **new, int *done, struct to
 
 static const struct got_error *
 view_input(struct tog_view **new, int *done, struct tog_view *view,
-    struct tog_view_list_head *views)
+    struct tog_view_list_head *views, int fast_refresh)
 {
 	const struct got_error *err = NULL;
 	struct tog_view *v;
@@ -1683,7 +1685,7 @@ view_input(struct tog_view **new, int *done, struct to
 	case '/':
 		view->count = 0;
 		if (view->search_start)
-			view_search_start(view);
+			view_search_start(view, fast_refresh);
 		else
 			err = view->input(new, view, ch);
 		break;
@@ -1775,7 +1777,7 @@ view_loop(struct tog_view *view)
 		if (fast_refresh && --fast_refresh == 0)
 			halfdelay(10); /* switch to once per second */
 
-		err = view_input(&new_view, &done, view, &views);
+		err = view_input(&new_view, &done, view, &views, fast_refresh);
 		if (err)
 			break;
 

> diff /home/misha/work/got
> commit - 704b1cf77bf5aa6f9aeed7bca0b34c53cc2183c2
> path + /home/misha/work/got
> blob - a6351da680ffacc2f47bf1a42b494d77af0b4a3a
> file + tog/tog.c
> --- tog/tog.c
> +++ tog/tog.c
> @@ -1747,7 +1747,6 @@ view_loop(struct tog_view *view)
>  	struct tog_view_list_head views;
>  	struct tog_view *new_view;
>  	char *mode;
> -	int fast_refresh = 10;
>  	int done = 0, errcode;
>  
>  	mode = getenv("TOG_VIEW_SPLIT_MODE");
> @@ -1771,9 +1770,7 @@ view_loop(struct tog_view *view)
>  	doupdate();
>  	while (!TAILQ_EMPTY(&views) && !done && !tog_thread_error &&
>  	    !tog_fatal_signal_received()) {
> -		/* Refresh fast during initialization, then become slower. */
> -		if (fast_refresh && --fast_refresh == 0)
> -			halfdelay(10); /* switch to once per second */
> +		halfdelay(10);
>  
>  		err = view_input(&new_view, &done, view, &views);
>  		if (err)
> 

-- 
Mark Jamsek <fnc.bsdbox.org>
GPG: F2FF 13DE 6A06 C471 CA80  E6E2 2930 DC66 86EE CF68