Skip to content

Instantly share code, notes, and snippets.

@zouppen
Last active August 29, 2015 14:01
Show Gist options
  • Save zouppen/ac5680f915c3a756cf81 to your computer and use it in GitHub Desktop.
Save zouppen/ac5680f915c3a756cf81 to your computer and use it in GitHub Desktop.
Gray coded binary clock in C
#include <sys/timerfd.h>
#include <err.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h> /* Definition of uint64_t */
#define GUARD(x) { if ((x)==-1) err(1,"Unable to initialize clock"); }
void init_clock(int *fd, time_t *now);
void put_binary(uint32_t x);
void init_clock(int *fd, time_t *now)
{
struct timespec start;
struct itimerspec spec;
GUARD(clock_gettime(CLOCK_REALTIME, &start));
*now = start.tv_sec;
/* Define a timer which starts exactly on the edge of next
* second and has interval of one second. */
spec.it_value.tv_sec = *now + 1;
spec.it_value.tv_nsec = 0;
spec.it_interval.tv_sec = 1;
spec.it_interval.tv_nsec = 0;
GUARD(*fd = timerfd_create(CLOCK_REALTIME, 0));
GUARD(timerfd_settime(*fd, TFD_TIMER_ABSTIME, &spec, NULL));
}
void put_binary(uint32_t x)
{
int i=32;
while (i--) {
putchar(x >> i & 1 ? '1' : '0');
}
}
int main(int argc, char *argv[])
{
int fd;
time_t now;
uint64_t ticks=0;
init_clock(&fd, &now);
while (1) {
if (ticks == 0) {
// We have "processed" all seconds, wait for more
ssize_t s = read(fd, &ticks, sizeof(uint64_t));
if (s != sizeof(uint64_t)) {
errx(2,"Timer reading error");
}
}
ticks--;
now++;
char humantime[30];
if (strftime(humantime,sizeof(humantime),"%F %H:%M:%S / ",localtime(&now)) == 0) {
errx(3,"Invalid date formatting");
}
fputs(humantime,stdout);
time_t gray = now >> 1 ^ now;
put_binary(gray);
putchar('\n');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment