On Sun, May 31, 2020 at 12:25:00AM -0400, George Koehler wrote: > On Sat, 30 May 2020 19:21:30 +0300 > Paul Irofti <p...@irofti.net> wrote: > > > Here is an updated diff with no libc bump. Please use this one for > > further testing. > > Your diff does amd64. > Here is a diff to add macppc. Apply after your diff.
Cool! Thanks for doing this! > I have only tested clock_gettime(2) with CLOCK_REALTIME, > by doing loops in Ruby like, $ ruby27 -e '10000.times{p Time.now}' > The time increased steadily, and ktrace showed only a few system calls > to clock_gettime(2). I am attaching a diff that includes minimal regression tests for this. You can also try testing with real programs such as Firefox. > I changed __amd64 to __amd64__ because I didn't find __powerpc. I'm > not sure, but one might move the list of arches to dlfcn/Makefile.inc > and do -DTIMEKEEP, like how thread/Makefile.inc does -DFUTEX. One > might drop the tc_get_timecount function pointer and just always call > the function #ifdef TIMEKEEP. That could work. First we have to decide on a name. Or maybe we already have, I don't know. > PowerPC Mac OS X had a userland gettimeofday(2) using the cpu's > timebase and a "common page" from the kernel. Their common page also > had executable code for gettimeofday, memcpy, pthread_self, and a few > other functions. --George That's a no-no for security reasons. The diff looks good. Please try it with more tests and real programs and report back. diff --git regress/lib/libc/timekeep/Makefile regress/lib/libc/timekeep/Makefile new file mode 100644 index 00000000000..a7f3080290d --- /dev/null +++ regress/lib/libc/timekeep/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD$ + +PROGS= test_clock_gettime test_time_skew test_gettimeofday + +.include <bsd.regress.mk> diff --git regress/lib/libc/timekeep/test_clock_gettime.c regress/lib/libc/timekeep/test_clock_gettime.c new file mode 100644 index 00000000000..859ec368215 --- /dev/null +++ regress/lib/libc/timekeep/test_clock_gettime.c @@ -0,0 +1,43 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2020 Paul Irofti <p...@irofti.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <time.h> + +#define ASSERT_EQ(a, b) assert((a) == (b)) + +void +check() +{ + struct timespec tp = {0}; + + ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &tp)); + ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &tp)); + ASSERT_EQ(0, clock_gettime(CLOCK_BOOTTIME, &tp)); + ASSERT_EQ(0, clock_gettime(CLOCK_UPTIME, &tp)); + + + ASSERT_EQ(0, clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tp)); + ASSERT_EQ(0, clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)); + +} + +int main() +{ + check(); + return 0; +} diff --git regress/lib/libc/timekeep/test_gettimeofday.c regress/lib/libc/timekeep/test_gettimeofday.c new file mode 100644 index 00000000000..ea90a1be7e0 --- /dev/null +++ regress/lib/libc/timekeep/test_gettimeofday.c @@ -0,0 +1,37 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2020 Paul Irofti <p...@irofti.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <sys/time.h> + +#define ASSERT_EQ(a, b) assert((a) == (b)) + +void +check() +{ + struct timeval tv = {0}; + struct timezone tzp; + + ASSERT_EQ(0, gettimeofday(&tv, NULL)); + ASSERT_EQ(0, gettimeofday(&tv, &tzp)); +} + +int main() +{ + check(); + return 0; +} diff --git regress/lib/libc/timekeep/test_time_skew.c regress/lib/libc/timekeep/test_time_skew.c new file mode 100644 index 00000000000..dfa9481c091 --- /dev/null +++ regress/lib/libc/timekeep/test_time_skew.c @@ -0,0 +1,55 @@ +/* $OpenBSD$ */ +/* + * Copyright (c) 2020 Paul Irofti <p...@irofti.net> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/time.h> + +#include <assert.h> +#include <time.h> +#include <stdlib.h> +#include <stdio.h> + +#define ASSERT_EQ(a, b) assert((a) == (b)) +#define ASSERT_NE(a, b) assert((a) != (b)) + +void +check() +{ + struct timespec tp1, tp2, tout; + + tout.tv_sec = 0; + tout.tv_nsec = 100000; + + ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &tp1)); + + nanosleep(&tout, NULL); + + ASSERT_EQ(0, clock_gettime(CLOCK_MONOTONIC, &tp2)); + + /* tp1 should never be larger than tp2 */ + ASSERT_NE(1, timespeccmp(&tp1, &tp2, >)); +} + +int +main(void) +{ + int i; + + for (i = 0; i < 1000; i++) + check(); + + return 0; +}