chiark / gitweb /
Enforce a minimum "low" time for the output.
authorBen Harris <bjh21@bjh21.me.uk>
Fri, 23 Nov 2018 23:26:59 +0000 (23:26 +0000)
committerBen Harris <bjh21@bjh21.me.uk>
Sat, 8 Dec 2018 22:30:09 +0000 (22:30 +0000)
By sleeping for 250 ms after each pulse, we ensure that even if
CLOCK_REALTIME is suddenly put forward by 29.7 seconds we won't start
a new pulse before the dial has recovered from the last one.

clunk.c

diff --git a/clunk.c b/clunk.c
index 7f10dc9ad61337ba63e6b664ab5e503213e4fe99..cb31782fb33565b78394328cadb8ac14106ffa13 100644 (file)
--- a/clunk.c
+++ b/clunk.c
  */
 static long const pulsewidth = 250000000; /* nanoseconds */
 
+/*
+ * Minimum gap between pulses.
+ */
+static long const gapwidth = 250000000; /* nanoseconds */
+
 /*
  * Maximum error to correct by advancing the clock rather than
  * stopping it, in seconds.  The point where it's faster to stop the
@@ -39,6 +44,9 @@ static sigset_t signals_to_block, timing_signals;
 
 static timer_t main_timer;
 
+#define TS_SEC(s) ((struct timespec){.tv_sec = s, .tv_nsec = 0})
+#define TS_NSEC(s) ((struct timespec){.tv_sec = 0, .tv_nsec = s})
+
 static void
 dummy_out(bool state)
 {
@@ -121,17 +129,21 @@ record_tick_finished(void)
 static void
 pulse()
 {
-       struct timespec const ts = { .tv_sec = 0, .tv_nsec = pulsewidth };
        sigset_t saved_mask;
 
        if (sigprocmask(SIG_BLOCK, &signals_to_block, &saved_mask) != 0)
                err(1, "sigprocmask(block)");
        (*outfn)(true);
        record_tick();
-       errno = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
+       errno = clock_nanosleep(CLOCK_MONOTONIC, 0,
+                               &TS_NSEC(pulsewidth), NULL);
        if (errno != 0)
                err(1, "clock_nanosleep");
        (*outfn)(false);
+       errno = clock_nanosleep(CLOCK_MONOTONIC, 0,
+                               &TS_NSEC(gapwidth), NULL);
+       if (errno != 0)
+               err(1, "clock_nanosleep");
        record_tick_finished();
        if (sigprocmask(SIG_SETMASK, &saved_mask, NULL) != 0)
                err(1, "sigprocmask(restore)");