Skip to content

Optimize standby event handling#10203

Merged
NiLuJe merged 8 commits into
masterfrom
unknown repository
Apr 5, 2023
Merged

Optimize standby event handling#10203
NiLuJe merged 8 commits into
masterfrom
unknown repository

Conversation

@ghost

@ghost ghost commented Mar 13, 2023

Copy link
Copy Markdown

Here I want to optimize the standby behavior, by minimizing the usage of the onEnterStandby and onLeaveStandby handlers.

The goal is to eliminate most of that handlers and optimize (speed) up the rest.
This can be achieved by just shifting the execution time of scheduled tasks by - Device.last_standby_time (notice the sign, which means they should be executed earlier.)
So it is not necessary to unschedule related tasks in onEnterStandby and reschedule them in onLeaveStandby.
The savings in the unschedule part might be smaller than the savings in the rescheduling part. (We will save a table delete and a binary insert in every case.)

As I won't eliminate the onXXXStandby events, everything will work as usual. The only difference is, that scheduled tasks will get executed last_standby_time earlier, as the clock has not ticked for exactly that last_standby_time (this is what we want, anyway).

This initial commit is just a POC with changes in the autosuspend-plugin together with header and footer (and a private userpatch). Seems to work so far.

  • autosuspend-plugin
  • plus UIManager
  • readerfooter
  • readercoptlistener
  • autowarmth-plugin
  • autoturn-plugin
  • autodim-plugin

As always: Throw thoughts on my brain until it gets muddy or find logical errors. ;-)


This change is Reviewable

@Frenzie Frenzie added the Plugin label Mar 13, 2023
Comment thread frontend/ui/uimanager.lua Outdated
@NiLuJe

This comment was marked as outdated.

@NiLuJe

NiLuJe commented Mar 13, 2023

Copy link
Copy Markdown
Member

On a purely theoretical level, I'm midly puzzled, because UIManager works on CLOCK_MONOTONIC, which does not tick during suspend/standby, so I would naively assume that rewinding shceduled task by the amount of time spent in standby would just wreak havoc?

Oh, wait, that's the whole point ;p. (I was mixing clock sources in my head, never mind me ;p).

@NiLuJe

NiLuJe commented Mar 13, 2023

Copy link
Copy Markdown
Member

It appears GitHub ate my first comment (or I'm so tired that I messed up ;p), so:

Just as a heads up, I won't be able to properly review/test this until next week ;).

@ghost

ghost commented Mar 13, 2023

Copy link
Copy Markdown
Author

Just as a heads up, I won't be able to properly review/test this until next week ;).

Absolutely no problem, as this is draft. I will have to figure out the open tasks and test it myself. You don't need to test it yourself until it is "ready for review". But I would appreciate anything jumping out :)

@ghost ghost marked this pull request as ready for review March 15, 2023 21:32
Comment thread plugins/autosuspend.koplugin/main.lua Outdated
@ghost

ghost commented Mar 17, 2023

Copy link
Copy Markdown
Author

@NiLuJe Rebased and ready from my side. But no hurry.

@ghost ghost marked this pull request as draft March 19, 2023 20:40
@ghost

ghost commented Mar 19, 2023

Copy link
Copy Markdown
Author

After rebaseing I got some strange behaviour. So draft now until I can explain or fix.

@ghost

ghost commented Mar 19, 2023

Copy link
Copy Markdown
Author

Update: I had plugged the device onto a different power source as usual (I knew, that the device sometimes gets crazy after using that charger), but forgot about that (but I am sure it was this way, now).
After two hours of bisecting and debug logs I restarted the device -> and voilà it works.
I am pretty sure, the charger-device combination doesn't fit and leaves the device in some strange state after using the charger (Kobo you have to be more generous in future).

So from my side no changes.

@ghost ghost marked this pull request as ready for review March 19, 2023 21:58
@ghost ghost added this to the 2023.04 milestone Mar 19, 2023
@NiLuJe

NiLuJe commented Mar 20, 2023

Copy link
Copy Markdown
Member

I've had the PowerCover break suspend in fun and interesting ways until a reboot, yeah...

@ghost

ghost commented Mar 29, 2023

Copy link
Copy Markdown
Author

Ready from my side.

@Frenzie Frenzie left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, but I haven't tested it yet

@NiLuJe

NiLuJe commented Mar 29, 2023

Copy link
Copy Markdown
Member

I've slacked off a bit, and only juuust started reinstalling my linux env, so I still haven't tried this either. Hopefully this weekend ;).

@ghost

ghost commented Apr 2, 2023

Copy link
Copy Markdown
Author

@NiLuJe Maybe off-topic here, but I don't want to open an additional issue for this. I am sure I saw this behavior before, and it can be provoked in the Terminal emulator (which has not been touched with this PR).

When playing with my Sage sometimes I get strange screen refreshes during reading. The refreshes look like that the screen is split into 4 parts, which are refreshed clockwise starting from the bottom left. Very fast, hard to follow.

I can provoke these refreshes in the Terminal emulator when entering:
echo standby > /sys/power/state
but not when entering:
sleep 3; echo standby > /sys/power/state

The refresh will always happen, when I get a write error: Operation not permitted; with the sleep command, there is no refresh and no write error.
Additionally, the device does not enter standby without the sleep.

Interestingly I found this strange refreshes during read, and I have also notices that the device sometimes does not enter standby.
This often happens, when enabling or disabling WiFi. I have spotted down a minimal change in the code to eliminate this special quirk.

But after seeing this, I looked closely to the fact, that the device does not enter standby.
Then I noticed two things:

  • With disabled notifications (Screen->Notifications) the device enters standby almost every time.
  • With enabled notification (my favorite) the device does not enter standby after showing a notification. Which would be schedule with scheduledIn(time, onClose). When reducing the time artificially to 0.5 seconds, the refresh never happens and the device goes to standby (but then you can't read the notification :-( ).

So I guess there might be a race hazard. I have tried to add a UIManager:waitForVSync() before entering standby (directly in device.lua) but this didn't help (in fact, I feel the behavior even gets worse).

Do you have any ideas about the root of the problem?
Thanks

@NiLuJe

NiLuJe commented Apr 2, 2023

Copy link
Copy Markdown
Member

When playing with my Sage sometimes I get strange screen refreshes during reading. The refreshes look like that the screen is split into 4 parts, which are refreshed clockwise starting from the bottom left. Very fast, hard to follow.

That's a kernel issue. It appeared with the first kernel update that touched the collision handling code (can't remember the FW version), and subsequent tweaks haven't really managed to entirely squash it.

It's specific to the Sage; the Elipsa has a different collision handling code (also broken, but slightly less user-visibly so).

@NiLuJe

NiLuJe commented Apr 2, 2023

Copy link
Copy Markdown
Member

FWIW, I hadn't traced it to PM at all, as the main spot I was seeing it was actually inside Nickel (and I wasn't the only one ^^); I've only very rarely seen in KOReader.

Then again, if I think about it, I think I added a slight delay to the screensaver display on sunxi because I was tripping another collision handling bug there (I don't think it was this exact one, though, but I can't quite remember), so it makes sense.

@NiLuJe

NiLuJe commented Apr 2, 2023

Copy link
Copy Markdown
Member

As for the Notification thing, that's interesting, but I'd be inclined to leave it alone: it's perfectly normal for PM to fail if it happens too soon after a screen update. We handle that gracefully by waiting for the timeout again, and since it's likely to be in the one digit range of seconds, it feels like a non-issue to me ;).

@NiLuJe

NiLuJe commented Apr 2, 2023

Copy link
Copy Markdown
Member

(Still have'nt had time to test this; I'm hoping to deal with it tomorrow, but we'll probably merge this tomorrow regardless, as it looks perfectly sensible to me ;)).

@NiLuJe

NiLuJe commented Apr 2, 2023

Copy link
Copy Markdown
Member

As for the Notification thing

The NO_MERGE flag might help (because it bypasses said broken collision handling codepath), but we're probably already using it for Notifications because of my last attempt at dealing with the Libra 2 crashes?

(Can't check right now, though).

@ghost

ghost commented Apr 3, 2023

Copy link
Copy Markdown
Author

I think I have solved that issue (minimal invasive) by adding

    if dirty then
        Screen:afterPaint()
        self.last_after_paint_time = self:getElapsedTimeSinceBoot()       -- add this line
    end

and test for time.to_number(now - UIManager.last_after_paint_time) > 2 before entering standby in the autosuspend plugin.

Anyway I want to test this solution and optimize the time distance (the 2) and move that maybe to a device specific property.
If successful, I will do that in a subsequent PR.

@NiLuJe

NiLuJe commented Apr 3, 2023

Copy link
Copy Markdown
Member

Fair warning: I'll probably veto something like that, FWIW ;).

@NiLuJe NiLuJe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few wording issues with some comments, but code looks good ;).

Speaking of comments, some stuff around self.going_to_suspend usage may also need to be reviewed (at least one of those instances mentions onLeaveStandby, which doesn't exist anymore).

Reviewed 2 of 4 files at r1, 4 of 5 files at r2, 1 of 1 files at r3, all commit messages.
Reviewable status: all files reviewed, 4 unresolved discussions (waiting on @zwim)


frontend/ui/uimanager.lua line 249 at r3 (raw file):

-- UIManager uses CLOCK_MONOTONIC (which doesn't tick during standby), so shifting the execution
-- time by a negative value will lead to an execution at the expected time.
-- @param time if positive execute the tasks later, if negative the should be executed earlier

nit: still a minor wording snafu left near the end there ;).


plugins/autosuspend.koplugin/main.lua line 644 at r3 (raw file):

        UIManager:consumeInputEarlyAfterPM(true)
        -- If we are leaving this method we are sure, that the input polling deadline is zero (consumeInputEarly).
        -- Then the input waiting is executed, so it is save to schedule a new task.

Second sentence is a tad clunky, making it hard to grok. (So's the comma placement in the first one, but that's less problematic).


plugins/autosuspend.koplugin/main.lua line 650 at r3 (raw file):

        end
    else
        -- If we are leaving this method we are sure, that the input polling deadline fits the next scheduled task (deadline).

Comment slightly unclear. That's simply input deadline >= next task, right?

@NiLuJe NiLuJe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One final nit ;).

Reviewed 2 of 2 files at r4, all commit messages.
Reviewable status: all files reviewed, 1 unresolved discussion (waiting on @zwim)


plugins/autosuspend.koplugin/main.lua line 644 at r4 (raw file):

        -- When we exit this method, we are sure that the input polling deadline is zero (consumeInputEarly).
        -- UIManagerger will check newly scheduled tasks before going to input polling again (with a new deadline).

nit: UIManager ;o).

@NiLuJe

NiLuJe commented Apr 4, 2023

Copy link
Copy Markdown
Member

Fair warning: I'll probably veto something like that, FWIW ;).

To expand a bit on that, I'm happy with the current behavior (i.e., that PM fails too soon after a screen update is perfectly normal, we should handle that properly (and we do)), so attempting to deal with this corner-case seems like gratuitous complexity at first glance.

On the other hand, if that happens to, as a byproduct, workaround a sunxi display driver issue, that's another kettle of fish, and I might be more lenient with this ;).

@NiLuJe NiLuJe left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 of 1 files at r5, all commit messages.
Reviewable status: :shipit: complete! all files reviewed, all discussions resolved (waiting on @zwim)

@NiLuJe NiLuJe merged commit 4dbaca1 into koreader:master Apr 5, 2023
@ghost ghost deleted the OptimizeStandby branch April 5, 2023 19:03
TranHHoang added a commit to TranHHoang/koreader that referenced this pull request May 26, 2023
KOReader 2023.04 "Solar Panel"

![koreader-2023-04-fs8](https://user-images.githubusercontent.com/202757/234975122-d7739c71-74aa-4cb0-a086-72a4bba70f52.png)

It's been another busy month squashing many bugs. Our Mac users will be happy to hear that I told macOS we've supported HiDPI since long before anyone came up with such terminology (koreader#10341), and that the program can now natively build on M1 devices (koreader#10291).

Solar panel credit: <https://openclipart.org/detail/294030/solar-energy> by gnokii

We'd like to thank all contributors for their efforts. Some highlights since the previous release include:

* Readerzooming: fix use of default settings (koreader#10205) @hius07
* ButtonDialog/ButtonDialogTitle: consistent 'width' handling (koreader#10230) @poire-z
* MovableContainer: add support for anchoring initial position (koreader#10230) @poire-z
* Book map, Page browser: add top left menu (koreader#10230) @poire-z
* Book style tweak: add button with CSS suggestions (koreader#10230) @poire-z
* crengine: fix parsing of multibytes encodings (koreader#10230) @poire-z
* readerstyletweak: update profiles on unregistering in dispatcher (koreader#10247) @hius07
* Filesearcher: add search in book metadata (koreader#10198) @hius07
* Fix: Updated legacy directory, which crashed the program (koreader#10260) @Mochitto
* ReaderLink: allow a forward location stack (koreader#10228) @yparitcher
* BookInfo: add page information (koreader#10255) @hius07
* Center pdf manual zoom mode (koreader#10246) @nairyosangha
* File browser: add Folder Menu (koreader#10275) @hius07
* Calendar view: add options to change start time of days (koreader#10254) @weijiuqiao
* filechooser: fix crash on "unreadable content" (koreader#10283) @hius07
* Sync book statistics: add to dispatcher (koreader#10285) @ptrm
* [plugin] Exporter: use util.getSafeFilename() to remove illegal characters from output filename (koreader#10282) @Mochitto
* readerbookmark: fix writing pdf annotation (koreader#10287) @hius07
* Folder Menu: sign for Home folder (koreader#10288) @hius07
* ListMenu: show mark for books with highlights (koreader#10276) @hius07
* Calendar view's day view: thicker separator at 00:00 (koreader#10289) @poire-z
* PageBrowser: tweak scrolling behaviour at book start/end (koreader#10289) @poire-z
* Make `kodev check` feature complete (koreader#8682) @yparitcher
* macOS: support for M1 building (koreader#10291) @ptrm
* Reader: do not apply font size and spacing out of range (koreader#10295, koreader#10307) @hius07
* File browser: show Folder Menu on long-press on Home icon (koreader#10298) @hius07
* SSH.koplugin: fix cant stop SSH server bug when pid file's stale (koreader#10300) @weijiuqiao
* PM: Optimize task queue handling around standby (koreader#10203) @zwim
* statistic.koplugin: fix today's timeline showing next day when within custom offset (koreader#10299) @weijiuqiao
* ReaderThumbnails: update cached page thumbnail on bookmark note change (koreader#10303) @hius07
* SDL: add multitouch support (koreader#10334) @Frenzie
* SDL: add HiDPI support (koreader#10341) @Frenzie
* BookInfo: fix crash on show cover (koreader#10315) @hius07
* Deal with table.pack corner-cases properly (koreader#10350) @NiLuJe
* Android: add Tagus Gea support (<koreader/android-luajit-launcher#412>) @Alfedi

[Full changelog](koreader/koreader@v2023.03...v2023.04) — [closed milestone issues](https://github.com/koreader/koreader/milestone/63?closed=1)

---

Installation instructions: [Android](https://github.com/koreader/koreader/wiki/Installation-on-Android-devices) • [Cervantes](https://github.com/koreader/koreader/wiki/Installation-on-BQ-devices) • [ChromeOS](https://github.com/koreader/koreader/wiki/Installation-on-Chromebook-devices) • [Kindle](https://github.com/koreader/koreader/wiki/Installation-on-Kindle-devices) • [Kobo](https://github.com/koreader/koreader/wiki/Installation-on-Kobo-devices) • [PocketBook](https://github.com/koreader/koreader/wiki/Installation-on-PocketBook-devices) • [ReMarkable](https://github.com/koreader/koreader/wiki/Installation-on-ReMarkable) • [Desktop Linux](https://github.com/koreader/koreader/wiki/Installation-on-desktop-linux) • [MacOS](https://github.com/koreader/koreader/wiki/Installation-on-MacOS)
0xstillb pushed a commit to 0xstillb/koreader-thai that referenced this pull request May 9, 2026
Instead of firing on(Enter|Leave)Standby Events, and having every other piece of code that might care about that handle re-scheduling their stuff themselves; simply make the standby implementation (i.e., AutoSuspend's) shift the whole task queue by the amount of time spent in standby to re-sync everything automatically.

(This is necessary in the first place because Linux, as the task queue ticks in CLOCK_MONOTONIC, which does *not* tick during suspend/standby; while we expect most of the tasks scheduled to actually reflect real world clock delays).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants