dwmblocks

Kris's build of dwmblocks
git clone git clone https://git.krisyotam.com/krisyotam/dwmblocks.git
Log | Files | Refs | README | LICENSE

timer.c (1814B)


      1 #include "timer.h"
      2 
      3 #include <errno.h>
      4 #include <stdbool.h>
      5 #include <stdio.h>
      6 #include <unistd.h>
      7 
      8 #include "block.h"
      9 #include "util.h"
     10 
     11 static unsigned int compute_tick(const block *const blocks,
     12                                  const unsigned short block_count) {
     13     unsigned int tick = 0;
     14 
     15     for (unsigned short i = 0; i < block_count; ++i) {
     16         const block *const block = &blocks[i];
     17         tick = gcd(block->interval, tick);
     18     }
     19 
     20     return tick;
     21 }
     22 
     23 static unsigned int compute_reset_value(const block *const blocks,
     24                                         const unsigned short block_count) {
     25     unsigned int reset_value = 1;
     26 
     27     for (unsigned short i = 0; i < block_count; ++i) {
     28         const block *const block = &blocks[i];
     29         reset_value = MAX(block->interval, reset_value);
     30     }
     31 
     32     return reset_value;
     33 }
     34 
     35 timer timer_new(const block *const blocks, const unsigned short block_count) {
     36     const unsigned int reset_value = compute_reset_value(blocks, block_count);
     37 
     38     timer timer = {
     39         .time = reset_value,  // Initial value to execute all blocks.
     40         .tick = compute_tick(blocks, block_count),
     41         .reset_value = reset_value,
     42     };
     43 
     44     return timer;
     45 }
     46 
     47 int timer_arm(timer *const timer) {
     48     errno = 0;
     49     (void)alarm(timer->tick);
     50 
     51     if (errno != 0) {
     52         (void)fprintf(stderr, "error: could not arm timer\n");
     53         return 1;
     54     }
     55 
     56     // Wrap `time` to the interval [1, reset_value].
     57     timer->time = (timer->time + timer->tick) % timer->reset_value;
     58 
     59     return 0;
     60 }
     61 
     62 bool timer_must_run_block(const timer *const timer, const block *const block) {
     63     if (timer == NULL || timer->time == timer->reset_value) {
     64         return true;
     65     }
     66 
     67     if (block->interval == 0) {
     68         return false;
     69     }
     70 
     71     return timer->time % block->interval == 0;
     72 }