1314817Sngie/* $NetBSD: t_getrusage.c,v 1.5 2017/01/13 20:31:06 christos Exp $ */ 2272343Sngie 3272343Sngie/*- 4272343Sngie * Copyright (c) 2011 The NetBSD Foundation, Inc. 5272343Sngie * All rights reserved. 6272343Sngie * 7272343Sngie * This code is derived from software contributed to The NetBSD Foundation 8272343Sngie * by Jukka Ruohonen. 9272343Sngie * 10272343Sngie * Redistribution and use in source and binary forms, with or without 11272343Sngie * modification, are permitted provided that the following conditions 12272343Sngie * are met: 13272343Sngie * 1. Redistributions of source code must retain the above copyright 14272343Sngie * notice, this list of conditions and the following disclaimer. 15272343Sngie * 2. Redistributions in binary form must reproduce the above copyright 16272343Sngie * notice, this list of conditions and the following disclaimer in the 17272343Sngie * documentation and/or other materials provided with the distribution. 18272343Sngie * 19272343Sngie * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20272343Sngie * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21272343Sngie * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22272343Sngie * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23272343Sngie * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24272343Sngie * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25272343Sngie * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26272343Sngie * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27272343Sngie * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28272343Sngie * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29272343Sngie * POSSIBILITY OF SUCH DAMAGE. 30272343Sngie */ 31272343Sngie#include <sys/cdefs.h> 32314817Sngie__RCSID("$NetBSD: t_getrusage.c,v 1.5 2017/01/13 20:31:06 christos Exp $"); 33272343Sngie 34272343Sngie#include <sys/resource.h> 35272343Sngie#include <sys/time.h> 36272343Sngie 37272343Sngie#include <atf-c.h> 38272343Sngie#include <errno.h> 39272343Sngie#include <limits.h> 40272343Sngie#include <signal.h> 41272343Sngie#include <stdint.h> 42272343Sngie#include <string.h> 43272343Sngie 44272343Sngiestatic void work(void); 45272343Sngiestatic void sighandler(int); 46272343Sngie 47272343Sngiestatic const size_t maxiter = 2000; 48272343Sngie 49272343Sngiestatic void 50276478Sngiesighandler(int signo __unused) 51272343Sngie{ 52272343Sngie /* Nothing. */ 53272343Sngie} 54272343Sngie 55313535Sngie#ifdef __FreeBSD__ 56313535Sngie#define asm __asm 57313535Sngie#endif 58313535Sngie 59272343Sngiestatic void 60272343Sngiework(void) 61272343Sngie{ 62272343Sngie size_t n = UINT16_MAX * 10; 63272343Sngie 64272343Sngie while (n > 0) { 65272343Sngie#ifdef __or1k__ 66272343Sngie asm volatile("l.nop"); /* Do something. */ 67313498Sngie#elif defined(__ia64__) 68313498Sngie asm volatile("nop 0"); /* Do something. */ 69272343Sngie#else 70272343Sngie asm volatile("nop"); /* Do something. */ 71272343Sngie#endif 72272343Sngie n--; 73272343Sngie } 74272343Sngie} 75272343Sngie 76272343SngieATF_TC(getrusage_err); 77272343SngieATF_TC_HEAD(getrusage_err, tc) 78272343Sngie{ 79272343Sngie atf_tc_set_md_var(tc, "descr", "Test error conditions"); 80272343Sngie} 81272343Sngie 82272343SngieATF_TC_BODY(getrusage_err, tc) 83272343Sngie{ 84272343Sngie struct rusage ru; 85272343Sngie 86272343Sngie errno = 0; 87272343Sngie 88272343Sngie ATF_REQUIRE(getrusage(INT_MAX, &ru) != 0); 89272343Sngie ATF_REQUIRE(errno == EINVAL); 90272343Sngie 91272343Sngie errno = 0; 92272343Sngie 93272343Sngie ATF_REQUIRE(getrusage(RUSAGE_SELF, (void *)0) != 0); 94272343Sngie ATF_REQUIRE(errno == EFAULT); 95272343Sngie} 96272343Sngie 97272343SngieATF_TC(getrusage_sig); 98272343SngieATF_TC_HEAD(getrusage_sig, tc) 99272343Sngie{ 100272343Sngie atf_tc_set_md_var(tc, "descr", "Test signal count with getrusage(2)"); 101272343Sngie} 102272343Sngie 103272343SngieATF_TC_BODY(getrusage_sig, tc) 104272343Sngie{ 105272343Sngie struct rusage ru; 106272343Sngie const long n = 5; 107272343Sngie int i; 108272343Sngie 109272343Sngie /* 110272343Sngie * Test that signals are recorded. 111272343Sngie */ 112272343Sngie ATF_REQUIRE(signal(SIGUSR1, sighandler) != SIG_ERR); 113272343Sngie 114272343Sngie for (i = 0; i < n; i++) 115272343Sngie ATF_REQUIRE(raise(SIGUSR1) == 0); 116272343Sngie 117272343Sngie (void)memset(&ru, 0, sizeof(struct rusage)); 118272343Sngie ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); 119272343Sngie 120272343Sngie if (n != ru.ru_nsignals) 121272343Sngie atf_tc_fail("getrusage(2) did not record signals"); 122272343Sngie} 123272343Sngie 124272343SngieATF_TC(getrusage_utime_back); 125272343SngieATF_TC_HEAD(getrusage_utime_back, tc) 126272343Sngie{ 127272343Sngie atf_tc_set_md_var(tc, "descr", "Test bogus values from getrusage(2)"); 128272343Sngie} 129272343Sngie 130272343SngieATF_TC_BODY(getrusage_utime_back, tc) 131272343Sngie{ 132272343Sngie struct rusage ru1, ru2; 133272343Sngie size_t i; 134272343Sngie 135272343Sngie /* 136272343Sngie * Test that two consecutive calls are sane. 137272343Sngie */ 138276478Sngie#ifdef __NetBSD__ 139272343Sngie atf_tc_expect_fail("PR kern/30115"); 140276478Sngie#endif 141272343Sngie 142272343Sngie for (i = 0; i < maxiter; i++) { 143272343Sngie 144272343Sngie (void)memset(&ru1, 0, sizeof(struct rusage)); 145272343Sngie (void)memset(&ru2, 0, sizeof(struct rusage)); 146272343Sngie 147272343Sngie work(); 148272343Sngie 149272343Sngie ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru1) == 0); 150272343Sngie 151272343Sngie work(); 152272343Sngie 153272343Sngie ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru2) == 0); 154272343Sngie 155272343Sngie if (timercmp(&ru2.ru_utime, &ru1.ru_utime, <) != 0) 156272343Sngie atf_tc_fail("user time went backwards"); 157272343Sngie } 158272343Sngie 159276478Sngie#ifdef __NetBSD__ 160272343Sngie atf_tc_fail("anticipated error did not occur"); 161276478Sngie#endif 162272343Sngie} 163272343Sngie 164272343SngieATF_TC(getrusage_utime_zero); 165272343SngieATF_TC_HEAD(getrusage_utime_zero, tc) 166272343Sngie{ 167272343Sngie atf_tc_set_md_var(tc, "descr", "Test zero utime from getrusage(2)"); 168272343Sngie} 169272343Sngie 170272343SngieATF_TC_BODY(getrusage_utime_zero, tc) 171272343Sngie{ 172272343Sngie struct rusage ru; 173272343Sngie size_t i; 174272343Sngie 175276478Sngie#ifdef __FreeBSD__ 176276478Sngie atf_tc_skip("this testcase passes/fails sporadically on FreeBSD/i386 " 177276478Sngie "@ r273153 (at least)"); 178276478Sngie#endif 179276478Sngie 180272343Sngie /* 181272343Sngie * Test that getrusage(2) does not return 182272343Sngie * zero user time for the calling process. 183272343Sngie * 184272343Sngie * See also (duplicate) PR port-amd64/41734. 185272343Sngie */ 186272343Sngie atf_tc_expect_fail("PR kern/30115"); 187272343Sngie 188272343Sngie for (i = 0; i < maxiter; i++) { 189272343Sngie 190272343Sngie work(); 191272343Sngie 192272343Sngie (void)memset(&ru, 0, sizeof(struct rusage)); 193272343Sngie 194272343Sngie ATF_REQUIRE(getrusage(RUSAGE_SELF, &ru) == 0); 195272343Sngie 196272343Sngie if (ru.ru_utime.tv_sec == 0 && ru.ru_utime.tv_usec == 0) 197272343Sngie atf_tc_fail("zero user time from getrusage(2)"); 198272343Sngie } 199272343Sngie 200272343Sngie atf_tc_fail("anticipated error did not occur"); 201272343Sngie} 202272343Sngie 203272343SngieATF_TP_ADD_TCS(tp) 204272343Sngie{ 205272343Sngie 206272343Sngie ATF_TP_ADD_TC(tp, getrusage_err); 207272343Sngie ATF_TP_ADD_TC(tp, getrusage_sig); 208272343Sngie ATF_TP_ADD_TC(tp, getrusage_utime_back); 209272343Sngie ATF_TP_ADD_TC(tp, getrusage_utime_zero); 210272343Sngie 211272343Sngie return atf_no_error(); 212272343Sngie} 213