---
slstatus.c | 47 +++++++++++++++++++++++++----------------------
1 file changed, 25 insertions(+), 22 deletions(-)
v3:
- replace CLOCK_REALTIME deadlines with mixed CLOCK_REALTIME/CLOCK_MONOTONIC
(REALTIME for alignment, MONOTONIC for absolute sleep — avoids suspend fragility)
- drop diff_ms classification (over-engineered for a status bar)
- revert datetime to time(NULL) (COARSE clock issue is one-frame only)
v2:
- classify next-now delta into advance/re-sleep/reanchor cases
- handle backward NTP steps
v1:
- initial CLOCK_REALTIME TIMER_ABSTIME approach
- switch datetime to clock_gettime(CLOCK_REALTIME)
diff --git a/slstatus.c b/slstatus.c
index 16d88fe..221b958 100644
--- a/slstatus.c
+++ b/slstatus.c
_AT_@ -4,6 +4,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <stdint.h>
#include <time.h>
#include <X11/Xlib.h>
_AT_@ -30,14 +31,6 @@ terminate(const int signo)
done = 1;
}
-static void
-difftimespec(struct timespec *res, struct timespec *a, struct timespec *b)
-{
- res->tv_sec = a->tv_sec - b->tv_sec - (a->tv_nsec < b->tv_nsec);
- res->tv_nsec = a->tv_nsec - b->tv_nsec +
- (a->tv_nsec < b->tv_nsec) * 1E9;
-}
-
static void
usage(void)
{
_AT_@ -48,7 +41,8 @@ int
main(int argc, char *argv[])
{
struct sigaction act;
- struct timespec start, current, diff, intspec, wait;
+ struct timespec wall, mono, deadline;
+ uint64_t wall_ns, offset_ns, interval_ns;
size_t i, len;
int sflag, ret;
char status[MAXLEN];
_AT_@ -82,10 +76,9 @@ main(int argc, char *argv[])
if (!sflag && !(dpy = XOpenDisplay(NULL)))
die("XOpenDisplay: Failed to open display");
- do {
- if (clock_gettime(CLOCK_MONOTONIC, &start) < 0)
- die("clock_gettime:");
+ interval_ns = interval * 1000000ULL;
+ do {
status[0] = '\0';
for (i = len = 0; i < LEN(args); i++) {
if (!(res = args[i].func(args[i].args)))
_AT_@ -110,18 +103,28 @@ main(int argc, char *argv[])
}
if (!done) {
- if (clock_gettime(CLOCK_MONOTONIC, ¤t) < 0)
+ if (clock_gettime(CLOCK_REALTIME, &wall) < 0 ||
+ clock_gettime(CLOCK_MONOTONIC, &mono) < 0)
die("clock_gettime:");
- difftimespec(&diff, ¤t, &start);
-
- intspec.tv_sec = interval / 1000;
- intspec.tv_nsec = (interval % 1000) * 1E6;
- difftimespec(&wait, &intspec, &diff);
- if (wait.tv_sec >= 0 &&
- nanosleep(&wait, NULL) < 0 &&
- errno != EINTR)
- die("nanosleep:");
+ wall_ns = (uint64_t)wall.tv_sec * 1000000000ULL + wall.tv_nsec;
+ offset_ns = interval_ns - (wall_ns % interval_ns);
+ if (offset_ns == interval_ns)
+ offset_ns = 0;
+
+ deadline.tv_sec = mono.tv_sec;
+ deadline.tv_nsec = mono.tv_nsec + (long)offset_ns;
+ if (deadline.tv_nsec >= 1000000000L) {
+ deadline.tv_sec++;
+ deadline.tv_nsec -= 1000000000L;
+ }
+
+ ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
+ &deadline, NULL);
+ if (ret != 0 && ret != EINTR) {
+ errno = ret;
+ die("clock_nanosleep:");
+ }
}
} while (!done);
--
2.47.3
Received on Sun May 31 2026 - 11:28:42 CEST
This archive was generated by hypermail 2.3.0 : Sun May 31 2026 - 11:36:36 CEST