On Mon, 4 Dec 2017 15:34:01 +0200 Alexandros Frantzis <[email protected]> wrote:
> Add a helper function to normalize struct timespec values so that the > nanoseconds part is less than 1 second and has the same sign as the > seconds part (if the seconds part is not 0). > > Normalization is required to ensure we can safely convert timespec > values to wayland protocol data, i.e, to tv_sec_hi, tv_sec_lo, > tv_sec_nsec triplets, and will be used in upcoming commits. > > Signed-off-by: Alexandros Frantzis <[email protected]> > --- > shared/timespec-util.h | 28 ++++++++++++++++++++++ > tests/timespec-test.c | 65 > ++++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 93 insertions(+) > > diff --git a/shared/timespec-util.h b/shared/timespec-util.h > index f9736c27..a10edf5b 100644 > --- a/shared/timespec-util.h > +++ b/shared/timespec-util.h > @@ -33,6 +33,34 @@ > > #define NSEC_PER_SEC 1000000000 > > +/* Normalize a timespec > + * > + * \param r[out] normalized timespec > + * \param a[in] timespec to normalize > + * > + * Normalize a timespec so that tv_nsec is less than 1 second > + * and has the same sign as tv_sec (if tv_sec is non-zero). Hi, why does it need to have the same sign? E.g. timespec_sub() ensures nsec is non-negative, as do the add functions. Otherwise this is fine, but I would also have the protocol spec forbid non-normalized timespec values like the presentation-timing extension does. Thanks, pq > + * > + */ > +static inline void > +timespec_normalize(struct timespec *r, const struct timespec *a) > +{ > + if (a->tv_nsec >= NSEC_PER_SEC || a->tv_nsec <= -NSEC_PER_SEC) { > + r->tv_sec = a->tv_sec + a->tv_nsec / NSEC_PER_SEC; > + r->tv_nsec = a->tv_nsec % NSEC_PER_SEC; > + } else { > + *r = *a; > + } > + > + if (r->tv_sec > 0 && r->tv_nsec < 0) { > + r->tv_sec -= 1; > + r->tv_nsec += NSEC_PER_SEC; > + } else if (r->tv_sec < 0 && r->tv_nsec > 0) { > + r->tv_sec += 1; > + r->tv_nsec -= NSEC_PER_SEC; > + } > +} > + > /* Subtract timespecs > * > * \param r[out] result: a - b > diff --git a/tests/timespec-test.c b/tests/timespec-test.c > index f127bcee..8c2296d1 100644 > --- a/tests/timespec-test.c > +++ b/tests/timespec-test.c > @@ -38,6 +38,71 @@ > #include "shared/helpers.h" > #include "zunitc/zunitc.h" > > +ZUC_TEST(timespec_test, timespec_normalize) > +{ > + struct timespec a, r; > + > + a.tv_sec = 0; > + a.tv_nsec = 0; > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, 0); > + ZUC_ASSERT_EQ(r.tv_nsec, 0); > + > + a.tv_sec = 1; > + a.tv_nsec = NSEC_PER_SEC - 1; > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, 1); > + ZUC_ASSERT_EQ(r.tv_nsec, NSEC_PER_SEC - 1); > + > + a.tv_sec = 1; > + a.tv_nsec = NSEC_PER_SEC; > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, 2); > + ZUC_ASSERT_EQ(r.tv_nsec, 0); > + > + a.tv_sec = 1; > + a.tv_nsec = NSEC_PER_SEC + 1; > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, 2); > + ZUC_ASSERT_EQ(r.tv_nsec, 1); > + > + a.tv_sec = -1; > + a.tv_nsec = -NSEC_PER_SEC; > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, -2); > + ZUC_ASSERT_EQ(r.tv_nsec, 0); > + > + a.tv_sec = -1; > + a.tv_nsec = -(NSEC_PER_SEC + 1); > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, -2); > + ZUC_ASSERT_EQ(r.tv_nsec, -1); > + > + a.tv_sec = -3; > + a.tv_nsec = NSEC_PER_SEC + 1; > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, -1); > + ZUC_ASSERT_EQ(r.tv_nsec, -(NSEC_PER_SEC - 1)); > + > + a.tv_sec = 3; > + a.tv_nsec = -(NSEC_PER_SEC + 1); > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, 1); > + ZUC_ASSERT_EQ(r.tv_nsec, NSEC_PER_SEC - 1); > + > + a.tv_sec = -1; > + a.tv_nsec = 2 * NSEC_PER_SEC + 1; > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, 1); > + ZUC_ASSERT_EQ(r.tv_nsec, 1); > + > + a.tv_sec = 1; > + a.tv_nsec = -(2 * NSEC_PER_SEC + 1); > + timespec_normalize(&r, &a); > + ZUC_ASSERT_EQ(r.tv_sec, -1); > + ZUC_ASSERT_EQ(r.tv_nsec, -1); > +} > + > ZUC_TEST(timespec_test, timespec_sub) > { > struct timespec a, b, r;
pgpCNtEK59w4d.pgp
Description: OpenPGP digital signature
_______________________________________________ wayland-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/wayland-devel
