GSoC Week 2 : Displays all loaded timers and calculates its next run time.

Harish Anand
2 min readMay 17, 2016

--

This week’s work was on the display of all loaded timers and calculation of its next run time and last run time. Request to have timer properties set via D-BUS was also filed to systemd last week. (https://github.com/systemd/systemd/issues/3234)

Calculation and creation of relative time stamps

The loaded timers can be listed out via the following command.

systemctl list-timers — all

This command displays loaded timers with next run time and time passed since last run. ( like 30min left and 29min ago ). I found the C code to it here https://github.com/systemd/systemd/blob/master/src/basic/time-util.c#L256 .

A JavaScript version of the systemd’s time conversion in C was created. It takes input in microseconds and outputs relative time-stamps.

Few examples :

format_timestamp_relative(1463509800000000) outputs “3h 60min left”.

format_timestamp_relative(1463499137000000) gives “49s ago”.

format_timestamp_relative(1463499167000) gives “46 years 3 months ago”.

Use Math.floor() to round to nearest integer for the results like here.

https://github.com/harishanand95/timer_mockup/blob/master/service.html#L147

Calculation of last run and next run time for timers using format_timestamp_relative function

  • To get Last Run (relative time) of a timer
var systemd_client = cockpit.dbus("org.freedesktop.systemd1", { superuser: "try" });var systemd_timer = systemd_client.proxy("org.freedesktop.systemd1.Timer",
"/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer");
format_timestamp_relative(systemd_timer.LastTriggerUSec);

systemd_timer.LastTriggerUSec gives time in CLOCK_REALTIME. We give it to format_timestamp_relative() as such.

  • To get Next Run (relative time) of a timer

Next Run time values can be CLOCK_REALTIME (for Calendar timers) and CLOCK_MONOTONIC (for Monotonic timers).

That’s why, timer D-BUS provides two properties to get next run time:

NextElapseUSecMonotonic and NextElapseUSecRealtime

If we have a calendar timer set, then NextElapseUSecRealtime will give the timer’s next run time in CLOCK_REALTIME.

If we have a monotonic timer set, then NextElapseUSecMonotonic will give the monotonic time from system startup time to next run (i.e not from Jan 1 1970). So to get the real time, we must add GeneratorsStartTimestamp of the systemd_manager object.

( As mentioned in paragraph 5 here, monotonic timers start from kernel startup. So we need to add system startup time to monotonic time to convert it to a real clock time. Here we use GeneratorsStartTimestamp to get an approximate system startup time.)

  1. Connect to both timer (any) and the manager object.
var systemd_client = cockpit.dbus("org.freedesktop.systemd1", { superuser: "try" });var systemd_manager =systemd_client.proxy("org.freedesktop.systemd1.Manager",
"/org/freedesktop/systemd1");
var systemd_timer
=systemd_client.proxy("org.freedesktop.systemd1.Timer",
"/org/freedesktop/systemd1/unit/systemd_2dtmpfiles_2dclean_2etimer");

2. Use manager object to get GeneratorsStartTimestamp.

if (systemd_timer.NextElapseUSecMonotonic > 0) {
time = systemd_manager.GeneratorsStartTimestamp + systemd_timer.NextElapseUSecMonotonic;
}
else {
time = systemd_timer.NextElapseUSecRealtime;
}
console.log(time);
format_timestamp_relative(time);

Here is the link to the currently developing timer playground app and a screenshot .

Meanwhile I’m also learning JavaScript during this community bonding phase as I’m a beginner to it.

--

--