Module: xenomai-3 Branch: next Commit: 19546c7fd8db33f6ca96509b7bf7f617ad5ef1f6 URL: http://git.xenomai.org/?p=xenomai-3.git;a=commit;h=19546c7fd8db33f6ca96509b7bf7f617ad5ef1f6
Author: Philippe Gerum <r...@xenomai.org> Date: Sat Jun 20 15:08:31 2015 +0200 testsuite/smokey: add timerfd testing code --- configure.ac | 1 + testsuite/regression/posix/Makefile.am | 3 +- testsuite/regression/posix/timerfd.c | 299 ------------------------ testsuite/smokey/Makefile.am | 2 + testsuite/smokey/timerfd/Makefile.am | 10 + testsuite/smokey/timerfd/timerfd.c | 389 ++++++++++++++++++++++++++++++++ 6 files changed, 403 insertions(+), 301 deletions(-) diff --git a/configure.ac b/configure.ac index c9aed45..43deedb 100644 --- a/configure.ac +++ b/configure.ac @@ -936,6 +936,7 @@ AC_CONFIG_FILES([ \ testsuite/smokey/iddp/Makefile \ testsuite/smokey/bufp/Makefile \ testsuite/smokey/sigdebug/Makefile \ + testsuite/smokey/timerfd/Makefile \ testsuite/clocktest/Makefile \ testsuite/xeno-test/Makefile \ testsuite/regression/Makefile \ diff --git a/testsuite/regression/posix/Makefile.am b/testsuite/regression/posix/Makefile.am index c878630..7998600 100644 --- a/testsuite/regression/posix/Makefile.am +++ b/testsuite/regression/posix/Makefile.am @@ -5,8 +5,7 @@ CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) noinst_HEADERS = check.h test_PROGRAMS = \ - leaks \ - timerfd + leaks CPPFLAGS = $(XENO_USER_CFLAGS) \ -I$(top_srcdir)/include diff --git a/testsuite/regression/posix/timerfd.c b/testsuite/regression/posix/timerfd.c deleted file mode 100644 index 086db62..0000000 --- a/testsuite/regression/posix/timerfd.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2013 Gilles Chanteperdrix <g...@xenomai.org> - * - * 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 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. - */ - -#undef NDEBUG -#include <stdio.h> -#include <unistd.h> -#include <errno.h> -#include <assert.h> -#include <fcntl.h> -#include <sys/timerfd.h> -#include "check.h" - -#ifndef TFD_NONBLOCK -#define TFD_NONBLOCK O_NONBLOCK -#endif - -static void timerfd_basic_check(void) -{ - struct itimerspec its; - int fd, i; - - check_unix(fd = timerfd_create(CLOCK_MONOTONIC, 0)); - - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 100000000; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 100000000; - - check_unix(timerfd_settime(fd, 0, &its, NULL)); - - for (i = 0; i < 10; i++) { - unsigned long long ticks; - - assert(check_unix(read(fd, &ticks, sizeof(ticks))) == 8); - fprintf(stderr, "%Ld direct read ticks\n", ticks); - assert(ticks >= 1); - } - - close(fd); -} - -static void timerfd_select_check(void) -{ - unsigned long long ticks; - struct itimerspec its; - fd_set inset; - int fd, i; - - check_unix(fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); - - FD_ZERO(&inset); - FD_SET(fd, &inset); - - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 100000000; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 100000000; - - check_unix(timerfd_settime(fd, 0, &its, NULL)); - assert(read(fd, &ticks, sizeof(ticks)) == -1 && errno == EAGAIN); - - for (i = 0; i < 10; i++) { - fd_set tmp_inset = inset; - - check_unix(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); - - assert(check_unix(read(fd, &ticks, sizeof(ticks))) == 8); - fprintf(stderr, "%Ld select+read ticks\n", ticks); - assert(ticks >= 1); - } - - close(fd); -} - -static void timerfd_basic_overruns_check(void) -{ - struct itimerspec its; - int fd, i; - - check_unix(fd = timerfd_create(CLOCK_MONOTONIC, 0)); - - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 100000000; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 100000000; - - check_unix(timerfd_settime(fd, 0, &its, NULL)); - - for (i = 0; i < 3; i++) { - unsigned long long ticks; - - sleep(1); - assert(check_unix(read(fd, &ticks, sizeof(ticks))) == 8); - fprintf(stderr, "%Ld direct read ticks\n", ticks); - assert(ticks >= 10); - } - - close(fd); -} - -static void timerfd_select_overruns_check(void) -{ - unsigned long long ticks; - struct itimerspec its; - fd_set inset; - int fd, i; - - check_unix(fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); - - FD_ZERO(&inset); - FD_SET(fd, &inset); - - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 100000000; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 100000000; - - check_unix(timerfd_settime(fd, 0, &its, NULL)); - assert(read(fd, &ticks, sizeof(ticks)) == -1 && errno == EAGAIN); - - for (i = 0; i < 3; i++) { - fd_set tmp_inset = inset; - - sleep(1); - check_unix(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); - - assert(check_unix(read(fd, &ticks, sizeof(ticks))) == 8); - fprintf(stderr, "%Ld select+read ticks\n", ticks); - assert(ticks >= 10); - } - - close(fd); -} - -static void timerfd_select_overruns2_check(void) -{ - unsigned long long ticks; - struct itimerspec its; - fd_set inset; - int fd, i; - - check_unix(fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); - - FD_ZERO(&inset); - FD_SET(fd, &inset); - - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 100000000; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 100000000; - - check_unix(timerfd_settime(fd, 0, &its, NULL)); - assert(read(fd, &ticks, sizeof(ticks)) == -1 && errno == EAGAIN); - - for (i = 0; i < 3; i++) { - fd_set tmp_inset = inset; - - check_unix(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); - - sleep(1); - - assert(check_unix(read(fd, &ticks, sizeof(ticks))) == 8); - fprintf(stderr, "%Ld select+read ticks\n", ticks); - assert(ticks >= 11); - } - - close(fd); -} - -static void timerfd_select_overruns_before_check(void) -{ - unsigned long long ticks; - struct itimerspec its; - fd_set inset; - int fd, i; - - check_unix(fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); - - FD_ZERO(&inset); - FD_SET(fd, &inset); - - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 100000000; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 100000000; - - check_unix(timerfd_settime(fd, 0, &its, NULL)); - assert(read(fd, &ticks, sizeof(ticks)) == -1 && errno == EAGAIN); - - sleep(1); - - for (i = 0; i < 3; i++) { - fd_set tmp_inset = inset; - - check_unix(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); - - assert(check_unix(read(fd, &ticks, sizeof(ticks))) == 8); - fprintf(stderr, "%Ld select+read ticks\n", ticks); - assert(ticks >= 10); - sleep(1); - } - - close(fd); -} - -static ssize_t -timed_read(int fd, void *buf, size_t len, struct timespec *ts) -{ - struct itimerspec its; - ssize_t err; - int tfd; - - check_unix(tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); - - its.it_value = *ts; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - - check_unix(timerfd_settime(tfd, TFD_WAKEUP, &its, NULL)); - - err = read(fd, buf, len); - if (err < 0) - err = -errno; - if (err == -EINTR) { - unsigned long long ticks; - - err = read(tfd, &ticks, sizeof(ticks)); - if (err > 0) - err = -ETIMEDOUT; - else - err = -EINTR; - } - - check_unix(close(tfd)); - - if (err >= 0) - return err; - - errno = -err; - return -1; -} - -static void timerfd_unblock_check(void) -{ - unsigned long long ticks; - struct itimerspec its; - int fd; - - check_unix(fd = timerfd_create(CLOCK_MONOTONIC, 0)); - - its.it_value.tv_sec = 5; - its.it_value.tv_nsec = 0; - its.it_interval.tv_sec = 0; - its.it_interval.tv_nsec = 0; - - check_unix(timerfd_settime(fd, 0, &its, NULL)); - - its.it_value.tv_sec = 0; - its.it_value.tv_nsec = 100000000; - - assert(timed_read(fd, &ticks, sizeof(ticks), &its.it_value) < 0 && - errno == ETIMEDOUT); - - check_unix(close(fd)); -} - - -int main(void) -{ - timerfd_basic_check(); - timerfd_select_check(); - timerfd_basic_overruns_check(); - timerfd_select_overruns_check(); - timerfd_select_overruns2_check(); - timerfd_select_overruns_before_check(); - timerfd_unblock_check(); - - return 0; -} diff --git a/testsuite/smokey/Makefile.am b/testsuite/smokey/Makefile.am index 397872e..d3bed8f 100644 --- a/testsuite/smokey/Makefile.am +++ b/testsuite/smokey/Makefile.am @@ -20,6 +20,7 @@ SUBDIRS = \ sched-quota \ sched-tp \ sigdebug \ + timerfd \ vdso-access \ xddp else @@ -61,5 +62,6 @@ DIST_SUBDIRS = \ sched-quota \ sched-tp \ sigdebug \ + timerfd \ vdso-access \ xddp diff --git a/testsuite/smokey/timerfd/Makefile.am b/testsuite/smokey/timerfd/Makefile.am new file mode 100644 index 0000000..27c3336 --- /dev/null +++ b/testsuite/smokey/timerfd/Makefile.am @@ -0,0 +1,10 @@ + +noinst_LIBRARIES = libtimerfd.a + +libtimerfd_a_SOURCES = timerfd.c + +CCLD = $(top_srcdir)/scripts/wrap-link.sh $(CC) + +libtimerfd_a_CPPFLAGS = \ + @XENO_USER_CFLAGS@ \ + -I$(top_srcdir)/include diff --git a/testsuite/smokey/timerfd/timerfd.c b/testsuite/smokey/timerfd/timerfd.c new file mode 100644 index 0000000..be9910a --- /dev/null +++ b/testsuite/smokey/timerfd/timerfd.c @@ -0,0 +1,389 @@ +/* + * Copyright (C) 2013 Gilles Chanteperdrix <g...@xenomai.org> + * + * 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 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 <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <assert.h> +#include <fcntl.h> +#include <sys/timerfd.h> +#include <smokey/smokey.h> + +smokey_test_plugin(timerfd, + SMOKEY_NOARGS, + "Check timerfd support." +); + +#ifndef TFD_NONBLOCK +#define TFD_NONBLOCK O_NONBLOCK +#endif + +static int timerfd_basic_check(void) +{ + unsigned long long ticks; + struct itimerspec its; + int fd, i, ret; + + fd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, 0)); + if (fd < 0) + return fd; + + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 100000000; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 100000000; + + ret = smokey_check_errno(timerfd_settime(fd, 0, &its, NULL)); + if (ret) + return ret; + + for (i = 0; i < 10; i++) { + ret = smokey_check_errno(read(fd, &ticks, sizeof(ticks))); + if (ret < 0) + return ret; + if (!smokey_assert(ret == 8)) + return -EINVAL; + smokey_note("%Ld direct read ticks", ticks); + if (!smokey_assert(ticks >= 1)) + return -EINVAL; + } + + return smokey_check_errno(close(fd)); +} + +static int timerfd_select_check(void) +{ + unsigned long long ticks; + fd_set tmp_inset, inset; + struct itimerspec its; + int fd, i, ret; + + fd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); + if (fd < 0) + return fd; + + FD_ZERO(&inset); + FD_SET(fd, &inset); + + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 100000000; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 100000000; + + ret = smokey_check_errno(timerfd_settime(fd, 0, &its, NULL)); + if (ret) + return ret; + + ret = read(fd, &ticks, sizeof(ticks)); + if (!smokey_assert(ret == -1 && errno == EAGAIN)) + return -EINVAL; + + for (i = 0; i < 10; i++) { + tmp_inset = inset; + ret = smokey_check_errno(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); + if (ret < 0) + return ret; + ret = smokey_check_errno(read(fd, &ticks, sizeof(ticks))); + if (ret < 0) + return ret; + smokey_assert(ret == 8); + smokey_note("%Ld select+read ticks", ticks); + if (!smokey_assert(ticks >= 1)) + return -EINVAL; + } + + return smokey_check_errno(close(fd)); +} + +static int timerfd_basic_overruns_check(void) +{ + unsigned long long ticks; + struct itimerspec its; + int fd, ret, i; + + fd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, 0)); + if (fd < 0) + return fd; + + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 100000000; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 100000000; + + ret = smokey_check_errno(timerfd_settime(fd, 0, &its, NULL)); + if (ret) + return ret; + + for (i = 0; i < 3; i++) { + sleep(1); + ret = smokey_check_errno(read(fd, &ticks, sizeof(ticks))); + if (ret < 0) + return ret; + smokey_assert(ret == 8); + smokey_note("%Ld direct read ticks", ticks); + if (!smokey_assert(ticks >= 10)) + return -EINVAL; + } + + return smokey_check_errno(close(fd)); +} + +static int timerfd_select_overruns_check(void) +{ + unsigned long long ticks; + fd_set tmp_inset, inset; + struct itimerspec its; + int fd, ret, i; + + fd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); + if (fd < 0) + return fd; + + FD_ZERO(&inset); + FD_SET(fd, &inset); + + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 100000000; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 100000000; + + ret = smokey_check_errno(timerfd_settime(fd, 0, &its, NULL)); + if (ret) + return ret; + + ret = read(fd, &ticks, sizeof(ticks)); + if (!smokey_assert(ret == -1 && errno == EAGAIN)) + return -EINVAL; + + for (i = 0; i < 3; i++) { + tmp_inset = inset; + sleep(1); + ret = smokey_check_errno(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); + if (ret < 0) + return ret; + ret = smokey_check_errno(read(fd, &ticks, sizeof(ticks))); + if (ret < 0) + return ret; + smokey_assert(ret == 8); + smokey_note("%Ld select+read ticks", ticks); + if (!smokey_assert(ticks >= 10)) + return -EINVAL; + } + + return smokey_check_errno(close(fd)); +} + +static int timerfd_select_overruns2_check(void) +{ + unsigned long long ticks; + fd_set tmp_inset, inset; + struct itimerspec its; + int fd, ret, i; + + fd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); + if (fd < 0) + return fd; + + FD_ZERO(&inset); + FD_SET(fd, &inset); + + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 100000000; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 100000000; + + ret = smokey_check_errno(timerfd_settime(fd, 0, &its, NULL)); + if (ret) + return ret; + + ret = read(fd, &ticks, sizeof(ticks)); + if (!smokey_assert(ret == -1 && errno == EAGAIN)) + return -EINVAL; + + for (i = 0; i < 3; i++) { + tmp_inset = inset; + ret = smokey_check_errno(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); + if (ret < 0) + return ret; + sleep(1); + ret = smokey_check_errno(read(fd, &ticks, sizeof(ticks))); + if (ret < 0) + return ret; + smokey_assert(ret == 8); + smokey_note("%Ld select+read ticks", ticks); + if (!smokey_assert(ticks >= 11)) + return -EINVAL; + } + + return smokey_check_errno(close(fd)); +} + +static int timerfd_select_overruns_before_check(void) +{ + unsigned long long ticks; + fd_set tmp_inset, inset; + struct itimerspec its; + int fd, ret, i; + + fd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); + if (fd < 0) + return fd; + + FD_ZERO(&inset); + FD_SET(fd, &inset); + + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 100000000; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 100000000; + + ret = smokey_check_errno(timerfd_settime(fd, 0, &its, NULL)); + if (ret) + return ret; + + ret = read(fd, &ticks, sizeof(ticks)); + if (!smokey_assert(ret == -1 && errno == EAGAIN)) + return -EINVAL; + + sleep(1); + + for (i = 0; i < 3; i++) { + tmp_inset = inset; + ret = smokey_check_errno(select(fd + 1, &tmp_inset, NULL, NULL, NULL)); + if (ret < 0) + return ret; + ret = smokey_check_errno(read(fd, &ticks, sizeof(ticks))); + if (ret < 0) + return ret; + smokey_assert(ret == 8); + smokey_note("%Ld select+read ticks", ticks); + if (!smokey_assert(ticks >= 10)) + return -EINVAL; + sleep(1); + } + + return smokey_check_errno(close(fd)); +} + +static ssize_t +timed_read(int fd, void *buf, size_t len, struct timespec *ts) +{ + unsigned long long ticks; + struct itimerspec its; + int tfd, ret; + ssize_t err; + + tfd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK)); + if (tfd < 0) + return tfd; + + its.it_value = *ts; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + + ret = smokey_check_errno(timerfd_settime(tfd, TFD_WAKEUP, &its, NULL)); + if (ret) + return ret; + + err = read(fd, buf, len); + if (err < 0) + err = -errno; + + if (err == -EINTR) { + err = read(tfd, &ticks, sizeof(ticks)); + if (err > 0) + err = -ETIMEDOUT; + else + err = -EINTR; + } + + ret = smokey_check_errno(close(tfd)); + if (ret) + return ret; + + if (err >= 0) + return err; + + errno = -err; + + return -1; +} + +static int timerfd_unblock_check(void) +{ + unsigned long long ticks; + struct itimerspec its; + int fd, ret; + + fd = smokey_check_errno(timerfd_create(CLOCK_MONOTONIC, 0)); + if (fd < 0) + return fd; + + its.it_value.tv_sec = 5; + its.it_value.tv_nsec = 0; + its.it_interval.tv_sec = 0; + its.it_interval.tv_nsec = 0; + + ret = smokey_check_errno(timerfd_settime(fd, 0, &its, NULL)); + if (ret) + return ret; + + its.it_value.tv_sec = 0; + its.it_value.tv_nsec = 100000000; + + if (!smokey_assert(timed_read(fd, &ticks, sizeof(ticks), &its.it_value) < 0 && + errno == ETIMEDOUT)) + return -EINVAL; + + return smokey_check_errno(close(fd)); +} + +static int run_timerfd(struct smokey_test *t, int argc, char *const argv[]) +{ + int ret; + + ret = timerfd_basic_check(); + if (ret) + return ret; + + timerfd_select_check(); + if (ret) + return ret; + + timerfd_basic_overruns_check(); + if (ret) + return ret; + + timerfd_select_overruns_check(); + if (ret) + return ret; + + timerfd_select_overruns2_check(); + if (ret) + return ret; + + timerfd_select_overruns_before_check(); + if (ret) + return ret; + + return timerfd_unblock_check(); +} _______________________________________________ Xenomai-git mailing list Xenomai-git@xenomai.org http://xenomai.org/mailman/listinfo/xenomai-git