[PATCH weston 1/7] timespec: Add timespec_add_nsec helper
Pekka Paalanen
ppaalanen at gmail.com
Tue Feb 14 14:09:57 UTC 2017
On Tue, 14 Feb 2017 13:18:01 +0000
Daniel Stone <daniels at collabora.com> wrote:
> Add a (timespec) = (timespec) + (nsec) helper, to save intermediate
> conversions to nanoseconds in its users.
>
> Signed-off-by: Daniel Stone <daniels at collabora.com>
Hi,
I recall some comments about using timespec over int64_t nanoseconds
being over-engineering, what do you think? Should we rather just
convert everything to int64_t nsec from the start and only deal with
them?
Personally I'm favour of timespec, even though int64_t nsec range is
+/- 290 years or so. :-)
> ---
> Makefile.am | 10 ++++
> shared/timespec-util.h | 21 +++++++++
> tests/timespec-test.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 157 insertions(+)
> create mode 100644 tests/timespec-test.c
>
> diff --git a/Makefile.am b/Makefile.am
> index dbdeea299..519d9115c 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -1194,6 +1194,7 @@ internal_tests = \
>
> shared_tests = \
> config-parser.test \
> + timespec.test \
> string.test \
> vertex-clip.test \
> zuctest
> @@ -1307,6 +1308,15 @@ config_parser_test_CFLAGS = \
> $(AM_CFLAGS) \
> -I$(top_srcdir)/tools/zunitc/inc
>
> +timespec_test_SOURCES = tests/timespec-test.c
> +timespec_test_LDADD = \
> + libshared.la \
> + libzunitc.la \
> + libzunitcmain.la
> +timespec_test_CFLAGS = \
> + $(AM_CFLAGS) \
> + -I$(top_srcdir)/tools/zunitc/inc
> +
Ooh, a zuc test!
> string_test_SOURCES = \
> tests/string-test.c \
> shared/string-helpers.h
> diff --git a/shared/timespec-util.h b/shared/timespec-util.h
> index edd4ec143..80b557859 100644
> --- a/shared/timespec-util.h
> +++ b/shared/timespec-util.h
> @@ -49,6 +49,27 @@ timespec_sub(struct timespec *r,
> }
> }
>
> +/* Add a nanosecond value to a timespec
> + *
> + * \param r[out] result: a + b
> + * \param a[in] base operand as timespec
> + * \param b[in] operand in nanoseconds
> + */
> +static inline void
> +timespec_add_nsec(struct timespec *r, const struct timespec *a, int64_t b)
> +{
> + r->tv_sec = a->tv_sec + (b / NSEC_PER_SEC);
> + r->tv_nsec = a->tv_nsec + (b % NSEC_PER_SEC);
> +
> + if (r->tv_nsec >= NSEC_PER_SEC) {
> + r->tv_sec++;
> + r->tv_nsec -= NSEC_PER_SEC;
> + } else if (r->tv_nsec <= -NSEC_PER_SEC) {
IIRC tv_nsec cannot be negative, so it should be:
r->tv_nsec < 0
I recall writing asserts for tv_nsec, but maybe it wasn't weston where
I did that.
I realize mandating 0 <= nsec < NSEC_PER_SEC to be somewhat arbitrary,
but timespec_sub() already assumes that and it is what
presentation-time protocol requires.
In wesgr where I needed the notion of invalid timestamps, I abused the
value tv_nsec = -1 for it.
> + r->tv_sec--;
> + r->tv_nsec += NSEC_PER_SEC;
> + }
> +}
Otherwise it looks correct.
> +
> /* Convert timespec to nanoseconds
> *
> * \param a timespec
> diff --git a/tests/timespec-test.c b/tests/timespec-test.c
> new file mode 100644
> index 000000000..f1193507a
> --- /dev/null
> +++ b/tests/timespec-test.c
> @@ -0,0 +1,126 @@
> +/*
> + * Copyright © 2016 Collabora, Ltd.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining
> + * a copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sublicense, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial
> + * portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
> + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
> + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
> + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
> + * SOFTWARE.
> + */
> +
> +#include "config.h"
> +
> +#include <stdlib.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <assert.h>
> +#include <errno.h>
> +#include <unistd.h>
> +
> +#include "timespec-util.h"
> +
> +#include "shared/helpers.h"
> +#include "zunitc/zunitc.h"
> +
> +#define NSEC_PER_SEC 1000000000
NSEC_PER_SEC should come from timespec-util.h.
> +
> +ZUC_TEST(timespec_test, timespec_sub)
> +{
> + struct timespec a, b, r;
> +
> + a.tv_sec = 1;
> + a.tv_nsec = 1;
> + b.tv_sec = 0;
> + b.tv_nsec = 2;
> + timespec_sub(&r, &a, &b);
> + ZUC_ASSERT_EQ(r.tv_sec, 0);
> + ZUC_ASSERT_EQ(r.tv_nsec, NSEC_PER_SEC - 1);
> +}
> +
> +ZUC_TEST(timespec_test, timespec_to_nsec)
> +{
> + struct timespec a;
> +
> + a.tv_sec = 4;
> + a.tv_nsec = 4;
> + ZUC_ASSERT_EQ(timespec_to_nsec(&a), (NSEC_PER_SEC * 4ULL) + 4);
> +}
> +
> +ZUC_TEST(timespec_test, millihz_to_nsec)
> +{
> + ZUC_ASSERT_EQ(millihz_to_nsec(60000), 16666666);
> +}
> +
> +ZUC_TEST(timespec_test, timespec_add_nsec)
> +{
> + struct timespec a, r;
An array and a loop to ease readability? :-)
> +
> + a.tv_sec = 0;
> + a.tv_nsec = NSEC_PER_SEC - 1;
> + timespec_add_nsec(&r, &a, 1);
> + ZUC_ASSERT_EQ(1, r.tv_sec);
> + ZUC_ASSERT_EQ(0, r.tv_nsec);
> +
> + timespec_add_nsec(&r, &a, 2);
> + ZUC_ASSERT_EQ(1, r.tv_sec);
> + ZUC_ASSERT_EQ(1, r.tv_nsec);
> +
> + timespec_add_nsec(&r, &a, (NSEC_PER_SEC * 2ULL));
> + ZUC_ASSERT_EQ(2, r.tv_sec);
> + ZUC_ASSERT_EQ(NSEC_PER_SEC - 1, r.tv_nsec);
> +
> + timespec_add_nsec(&r, &a, (NSEC_PER_SEC * 2ULL) + 2);
> + ZUC_ASSERT_EQ(r.tv_sec, 3);
> + ZUC_ASSERT_EQ(r.tv_nsec, 1);
> +
All correct up to here.
> + a.tv_sec = 0;
> + a.tv_nsec = 1;
> + timespec_add_nsec(&r, &a, -2);
> + ZUC_ASSERT_EQ(r.tv_sec, 0);
> + ZUC_ASSERT_EQ(r.tv_nsec, -1);
Incorrect, tv_nsec cannot be negative.
> +
> + a.tv_nsec = 0;
> + timespec_add_nsec(&r, &a, -NSEC_PER_SEC);
> + ZUC_ASSERT_EQ(-1, r.tv_sec);
> + ZUC_ASSERT_EQ(0, r.tv_nsec);
Correct.
> +
> + a.tv_nsec = -1;
Invalid timestamp.
> + timespec_add_nsec(&r, &a, -NSEC_PER_SEC + 1);
> + ZUC_ASSERT_EQ(-1, r.tv_sec);
> + ZUC_ASSERT_EQ(0, r.tv_nsec);
> +
> + a.tv_nsec = 50;
> + timespec_add_nsec(&r, &a, (-NSEC_PER_SEC * 10ULL));
> + ZUC_ASSERT_EQ(-10, r.tv_sec);
> + ZUC_ASSERT_EQ(50, r.tv_nsec);
Correct.
> +
> + r.tv_sec = 4;
> + r.tv_nsec = 0;
> + timespec_add_nsec(&r, &r, NSEC_PER_SEC + 10ULL);
> + ZUC_ASSERT_EQ(5, r.tv_sec);
> + ZUC_ASSERT_EQ(10, r.tv_nsec);
> +
> + timespec_add_nsec(&r, &r, (NSEC_PER_SEC * 3ULL) - 9ULL);
> + ZUC_ASSERT_EQ(8, r.tv_sec);
> + ZUC_ASSERT_EQ(1, r.tv_nsec);
> +
> + timespec_add_nsec(&r, &r, (NSEC_PER_SEC * 7ULL) + (NSEC_PER_SEC - 1ULL));
> + ZUC_ASSERT_EQ(16, r.tv_sec);
> + ZUC_ASSERT_EQ(0, r.tv_nsec);
> +}
Correct.
Thanks,
pq
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 801 bytes
Desc: OpenPGP digital signature
URL: <https://lists.freedesktop.org/archives/wayland-devel/attachments/20170214/7df4e552/attachment.sig>
More information about the wayland-devel
mailing list