[PATCH weston 1/8] shared: Add timespec_normalize helper

Pekka Paalanen ppaalanen at gmail.com
Tue Dec 12 09:50:49 UTC 2017


On Mon,  4 Dec 2017 15:34:01 +0200
Alexandros Frantzis <alexandros.frantzis at collabora.com> 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 <alexandros.frantzis at collabora.com>
> ---
>  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;

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20171212/a8efb00d/attachment.sig>


More information about the wayland-devel mailing list