1 week bump.
--
Scott Cheloha
> On Aug 5, 2017, at 8:25 PM, Scott Cheloha wrote:
>
> Hi,
>
> In tetris(6) we use gettimeofday(2) to determine (roughly) how
> long we polled for user input. This then gets subtracted from
> the time remaining until we drop the block another row.
>
> This should be computed with a monotonic clock instead, lest
> bullshit like clock drift rob you of that crucial tenth of a
> second and cost you your new high score.
>
> Moving to a monotonic clock implies using nanoseconds instead of
> microseconds, but this actually turns out to be kind of nice
> because ppoll(2) accepts a timespec structure, so then we can
> delete a few things we were using to jam a timeval into poll(2).
>
> I've playtested a bit and it doesn't ~feel~ any different. If
> anything the game *should* feel less choppy under certain
> conditions, though I can't really prove that.
>
> Feedback?
>
> --
> Scott Cheloha
>
> Index: games/tetris/input.c
> ===
> RCS file: /cvs/src/games/tetris/input.c,v
> retrieving revision 1.18
> diff -u -p -r1.18 input.c
> --- games/tetris/input.c 27 Aug 2016 02:02:44 - 1.18
> +++ games/tetris/input.c 6 Aug 2017 01:21:41 -
> @@ -40,89 +40,75 @@
> */
>
> #include
> +
> #include
> #include
> +#include
> #include
>
> #include "input.h"
> #include "tetris.h"
>
> -/* return true iff the given timeval is positive */
> -#define TV_POS(tv) \
> - ((tv)->tv_sec > 0 || ((tv)->tv_sec == 0 && (tv)->tv_usec > 0))
> -
> -/* subtract timeval `sub' from `res' */
> -#define TV_SUB(res, sub) \
> - (res)->tv_sec -= (sub)->tv_sec; \
> - (res)->tv_usec -= (sub)->tv_usec; \
> - if ((res)->tv_usec < 0) { \
> - (res)->tv_usec += 100; \
> - (res)->tv_sec--; \
> - }
> +/* return true iff the given timespec is positive */
> +#define TS_POS(ts) \
> + ((ts)->tv_sec > 0 || ((ts)->tv_sec == 0 && (ts)->tv_nsec > 0))
>
> /*
> - * Do a `read wait': poll for reading from stdin, with timeout *tvp.
> - * On return, modify *tvp to reflect the amount of time spent waiting.
> + * Do a `read wait': poll for reading from stdin, with timeout *limit.
> + * On return, subtract the time spent waiting from *limit.
> * It will be positive only if input appeared before the time ran out;
> * otherwise it will be zero or perhaps negative.
> *
> - * If tvp is nil, wait forever, but return if poll is interrupted.
> + * If limit is NULL, wait forever, but return if poll is interrupted.
> *
> - * Return 0 => no input, 1 => can read() from stdin
> + * Return 0 => no input, 1 => can read() from stdin, -1 => interrupted
> */
> int
> -rwait(struct timeval *tvp)
> +rwait(struct timespec *limit)
> {
> - int timo = INFTIM;
> - struct timeval starttv, endtv;
> + struct timespec start, end, elapsed;
> struct pollfd pfd[1];
>
> -#define NILTZ ((struct timezone *)0)
> -
> - if (tvp) {
> - (void) gettimeofday(, NILTZ);
> - endtv = *tvp;
> - timo = endtv.tv_sec * 1000 + endtv.tv_usec / 1000;
> - }
> -again:
> pfd[0].fd = STDIN_FILENO;
> pfd[0].events = POLLIN;
> - switch (poll(pfd, 1, timo)) {
> +
> + if (limit != NULL)
> + clock_gettime(CLOCK_MONOTONIC, );
> +again:
> + switch (ppoll(pfd, 1, limit, NULL)) {
> case -1:
> - if (tvp == 0)
> + if (limit == NULL)
> return (-1);
> if (errno == EINTR)
> goto again;
> stop("poll failed, help");
> -
> case 0: /* timed out */
> - tvp->tv_sec = 0;
> - tvp->tv_usec = 0;
> + timespecclear(limit);
> return (0);
> }
> - if (tvp) {
> - /* since there is input, we may not have timed out */
> - (void) gettimeofday(, NILTZ);
> - TV_SUB(, );
> - TV_SUB(tvp, );/* adjust *tvp by elapsed time */
> + if (limit != NULL) {
> + /* we have input, so subtract the elapsed time from *limit */
> + clock_gettime(CLOCK_MONOTONIC, );
> + timespecsub(, , );
> + timespecsub(limit, , limit);
> }
> return (1);
> }
>
> /*
> - * `sleep' for the current turn time (using poll).
> - * Eat any input that might be available.
> + * `sleep' for the current turn time and eat any
> + * input that becomes available.
> */
> void
> tsleep(void)
> {
> - struct timeval tv;
> + struct timespec ts;
> char c;
>
> - tv.tv_sec = 0;
> - tv.tv_usec = fallrate;
> - while (TV_POS())
> - if (rwait() && read(STDIN_FILENO, , 1) != 1)
> + ts.tv_sec = 0;
> + ts.tv_nsec = fallrate;
> + while (TS_POS())
> + if (rwait() && read(STDIN_FILENO, , 1) != 1)
> break;
> }
>
> @@ -132,7 +118,7 @@