From 10d708d2688f26c17b3f009fcc681174d9877166 Mon Sep 17 00:00:00 2001 From: Alexandros Frantzis Date: Wed, 13 Dec 2017 13:27:54 +0200 Subject: [PATCH] shared: Add timespec_to_proto helper function Add helper function to convert from struct timespec values to tv_sec_hi, tv_sec_lo, tv_nsec triplets used for sending high-resolution timestamp data over the wayland protocol. Replace existing conversion code with the helper function. Signed-off-by: Alexandros Frantzis Reviewed-by: Pekka Paalanen --- libweston/compositor.c | 9 +++++---- shared/timespec-util.h | 24 ++++++++++++++++++++++++ tests/timespec-test.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/libweston/compositor.c b/libweston/compositor.c index 7d7a17e..083664f 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -341,7 +341,9 @@ weston_presentation_feedback_present( { struct wl_client *client = wl_resource_get_client(feedback->resource); struct wl_resource *o; - uint64_t secs; + uint32_t tv_sec_hi; + uint32_t tv_sec_lo; + uint32_t tv_nsec; wl_resource_for_each(o, &output->resource_list) { if (wl_resource_get_client(o) != client) @@ -350,10 +352,9 @@ weston_presentation_feedback_present( wp_presentation_feedback_send_sync_output(feedback->resource, o); } - secs = ts->tv_sec; + timespec_to_proto(ts, &tv_sec_hi, &tv_sec_lo, &tv_nsec); wp_presentation_feedback_send_presented(feedback->resource, - secs >> 32, secs & 0xffffffff, - ts->tv_nsec, + tv_sec_hi, tv_sec_lo, tv_nsec, refresh_nsec, seq >> 32, seq & 0xffffffff, flags | feedback->psf_flags); diff --git a/shared/timespec-util.h b/shared/timespec-util.h index 5184d28..5f4b2b9 100644 --- a/shared/timespec-util.h +++ b/shared/timespec-util.h @@ -147,6 +147,30 @@ timespec_to_usec(const struct timespec *a) return (int64_t)a->tv_sec * 1000000 + a->tv_nsec / 1000; } +/* Convert timespec to protocol data + * + * \param a timespec + * \param tv_sec_hi[out] the high bytes of the seconds part + * \param tv_sec_lo[out] the low bytes of the seconds part + * \param tv_nsec[out] the nanoseconds part + * + * The input timespec must be normalized (the nanoseconds part should + * be less than 1 second) and non-negative. + */ +static inline void +timespec_to_proto(const struct timespec *a, uint32_t *tv_sec_hi, + uint32_t *tv_sec_lo, uint32_t *tv_nsec) +{ + assert(a->tv_sec >= 0); + assert(a->tv_nsec >= 0 && a->tv_nsec < NSEC_PER_SEC); + + uint64_t sec64 = a->tv_sec; + + *tv_sec_hi = sec64 >> 32; + *tv_sec_lo = sec64 & 0xffffffff; + *tv_nsec = a->tv_nsec; +} + /* Convert nanoseconds to timespec * * \param a timespec diff --git a/tests/timespec-test.c b/tests/timespec-test.c index a4d8dcf..54230f8 100644 --- a/tests/timespec-test.c +++ b/tests/timespec-test.c @@ -79,6 +79,35 @@ ZUC_TEST(timespec_test, timespec_to_msec) ZUC_ASSERT_EQ(timespec_to_msec(&a), (4000ULL) + 4); } +ZUC_TEST(timespec_test, timespec_to_proto) +{ + struct timespec a; + uint32_t tv_sec_hi; + uint32_t tv_sec_lo; + uint32_t tv_nsec; + + a.tv_sec = 0; + a.tv_nsec = 0; + timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec); + ZUC_ASSERT_EQ(0, tv_sec_hi); + ZUC_ASSERT_EQ(0, tv_sec_lo); + ZUC_ASSERT_EQ(0, tv_nsec); + + a.tv_sec = 1234; + a.tv_nsec = NSEC_PER_SEC - 1; + timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec); + ZUC_ASSERT_EQ(0, tv_sec_hi); + ZUC_ASSERT_EQ(1234, tv_sec_lo); + ZUC_ASSERT_EQ(NSEC_PER_SEC - 1, tv_nsec); + + a.tv_sec = (time_t)0x7000123470005678LL; + a.tv_nsec = 1; + timespec_to_proto(&a, &tv_sec_hi, &tv_sec_lo, &tv_nsec); + ZUC_ASSERT_EQ((uint64_t)a.tv_sec >> 32, tv_sec_hi); + ZUC_ASSERT_EQ(0x70005678, tv_sec_lo); + ZUC_ASSERT_EQ(1, tv_nsec); +} + ZUC_TEST(timespec_test, millihz_to_nsec) { ZUC_ASSERT_EQ(millihz_to_nsec(60000), 16666666); -- 2.7.4