💾 Archived View for missbanal.net › another-cron captured on 2024-05-10 at 10:27:44. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Published the 2024-05-01 on Willow's site
Sxmo is a Desktop Environment that primarily target embedded devices with not-so-tiny screens we will name here "Smartphones". It is based on a common Linux software stack, and in a more structuring way Tiling Windows Managers (at the moment sway, dwm).
Today to improve battery longevity, we rely a lot on System Suspension. Which means the OS will shut down most of the hardware, and only some subsystems as Modem and RAM Memory will be kept running. It means that the system is unusable until it woke up again. This happens of course when the user presses the power hardware button. But the system can also be woken up by the modem, on incoming calls or SMS.
But then come a common problem: How the user can schedule a task to run periodically?
This is a solved issue in a Linux world. Most of the time the system is always alive, so let's just wait for the correct moment to comes. A simple script could just wait for some time, run the user command, and then re-do. But if the user need a more complex scheduler, they generally use a Cronjob Scheduler. If you need to play a song every week-day at 07 AM to wake YOU up: write a crontab entry.
In Sxmo we tried to preserve some control over the system suspension to use Cronjob Schedulers. We wrote mnc which is a simple software that parse crontab files, and output the time in second until the next crontab entry (My Next Cron). Then we use this duration to prepare the suspension to sleep until this next job. The system would then sleep, and wake up just in time for the scheduler to trigger the task.
mnc - find seconds to next cronjob
Yes! Yes? It never worked… Here is the ticket I wrote, and updated over time to track this:
#384: Still unreliable rtc wake with cronjobs
It looks like the scheduler loose track of the passed time, while the device was sleeping. With chronie, the job will just never trigger. With fcron, a theoretically more safe with suspension cron scheduler, it can take up to 45 minutes, or more, for the task to actually start.
Those Cronjobs Scheduler was just not implemented with suspension in mind. Working around them does not work. But there was a simpler way. I started to implement Mcron, a mobile cron job scheduler.
mcron: a sleeping Cron Job Scheduler
Mcron does job scheduling in a sleeping way. Instead of tracking time, and checking periodically if the job moments are now, it computes the duration until the next job moments. It creates timer file descriptors in the kernel space, and then it just waits for them to expires, with a simple read system call. And to make the system to wake up when it does, it uses the CLOCK_REALTIME_ALARM system clock.
CLOCK_REALTIME_ALARM (since Linux 3.11)
This clock is like CLOCK_REALTIME, but will wake the system if
it is suspended.
Designed this way, Sxmo does not have to do anything. It will work on any Linux operating system.
I program with the Hare programming language for some time now, and I recently used a lot the hare-ev event loop. I knew this was really trivial to implement with.
Mcron is not packaged yet, because it still depends on some Hare edge patches. But everything has been upstreamed now. And I will package it with the next Hare release.
I had to send to the upstream stdlib a tiny patch to help with reading system group. And I worked with Byron Torres, that maintains the Hare date/time support, to fill a hole when creating date time object while switching to different timezone offset.
But, It just works.
I probably spent a whole weekend time implementing it, writing man pages documentation, and improving the duration computation algorithm. It makes sure the users belongs to the mcron group, and start the task with the correct user authorizations. I expect it is safe to use.
If this post inspired you, feels free to leave a comment !