t_nice.c revision 276478
1164190Sjkoshy/* $NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $ */ 2164190Sjkoshy 3164190Sjkoshy/*- 4164190Sjkoshy * Copyright (c) 2011 The NetBSD Foundation, Inc. 5164190Sjkoshy * All rights reserved. 6164190Sjkoshy * 7164190Sjkoshy * This code is derived from software contributed to The NetBSD Foundation 8164190Sjkoshy * by Jukka Ruohonen. 9164190Sjkoshy * 10164190Sjkoshy * Redistribution and use in source and binary forms, with or without 11164190Sjkoshy * modification, are permitted provided that the following conditions 12164190Sjkoshy * are met: 13164190Sjkoshy * 1. Redistributions of source code must retain the above copyright 14164190Sjkoshy * notice, this list of conditions and the following disclaimer. 15164190Sjkoshy * 2. Redistributions in binary form must reproduce the above copyright 16164190Sjkoshy * notice, this list of conditions and the following disclaimer in the 17164190Sjkoshy * documentation and/or other materials provided with the distribution. 18164190Sjkoshy * 19164190Sjkoshy * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20164190Sjkoshy * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21165535Sjkoshy * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22164190Sjkoshy * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23164190Sjkoshy * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24164190Sjkoshy * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25164190Sjkoshy * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26164190Sjkoshy * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27164190Sjkoshy * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28165317Sjkoshy * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29164190Sjkoshy * POSSIBILITY OF SUCH DAMAGE. 30164190Sjkoshy */ 31164190Sjkoshy#include <sys/cdefs.h> 32165317Sjkoshy__RCSID("$NetBSD: t_nice.c,v 1.8 2012/03/18 07:00:51 jruoho Exp $"); 33165317Sjkoshy 34165317Sjkoshy#include <sys/resource.h> 35164190Sjkoshy#include <sys/wait.h> 36164190Sjkoshy 37164190Sjkoshy#include <atf-c.h> 38164190Sjkoshy#include <errno.h> 39164190Sjkoshy#include <limits.h> 40165317Sjkoshy#include <pthread.h> 41164190Sjkoshy#include <stdlib.h> 42164190Sjkoshy#include <unistd.h> 43164190Sjkoshy 44164190Sjkoshystatic void *threadfunc(void *); 45164190Sjkoshy 46164190Sjkoshystatic void * 47210348Skaiwthreadfunc(void *arg) 48164190Sjkoshy{ 49164190Sjkoshy int pri, val; 50164190Sjkoshy 51165535Sjkoshy val = *(int *)arg; 52164190Sjkoshy 53164190Sjkoshy errno = 0; 54164225Sjkoshy pri = getpriority(PRIO_PROCESS, 0); 55164225Sjkoshy ATF_REQUIRE(errno == 0); 56164190Sjkoshy 57164190Sjkoshy if (pri != val) 58237528Sandrew atf_tc_fail("nice(3) value was not propagated to threads"); 59237528Sandrew 60237528Sandrew return NULL; 61237528Sandrew} 62237528Sandrew 63237528SandrewATF_TC(nice_err); 64237528SandrewATF_TC_HEAD(nice_err, tc) 65237528Sandrew{ 66164577Sru atf_tc_set_md_var(tc, "descr", 67164577Sru "Test nice(3) for invalid parameters (PR lib/42587)"); 68237531Sandrew atf_tc_set_md_var(tc, "require.user", "unprivileged"); 69237528Sandrew} 70164190Sjkoshy 71238741SacheATF_TC_BODY(nice_err, tc) 72238741Sache{ 73237528Sandrew int i; 74237528Sandrew 75164190Sjkoshy#ifdef __FreeBSD__ 76164190Sjkoshy atf_tc_expect_fail("nice(incr) with incr < 0 fails with unprivileged " 77164190Sjkoshy "users and sets errno == EPERM; see PR # 189821 for more details"); 78164190Sjkoshy#endif 79164190Sjkoshy 80210345Skaiw /* 81210345Skaiw * The call should fail with EPERM if the 82164190Sjkoshy * supplied parameter is negative and the 83164190Sjkoshy * caller does not have privileges. 84164190Sjkoshy */ 85164190Sjkoshy for (i = -20; i < 0; i++) { 86164190Sjkoshy 87164190Sjkoshy errno = 0; 88164190Sjkoshy 89164190Sjkoshy ATF_REQUIRE_ERRNO(EPERM, nice(i) == -1); 90210345Skaiw } 91165535Sjkoshy} 92210345Skaiw 93164190SjkoshyATF_TC(nice_priority); 94210345SkaiwATF_TC_HEAD(nice_priority, tc) 95164190Sjkoshy{ 96164190Sjkoshy atf_tc_set_md_var(tc, "descr", "Test nice(3) vs. getpriority(2)"); 97164190Sjkoshy} 98164190Sjkoshy 99164190SjkoshyATF_TC_BODY(nice_priority, tc) 100164190Sjkoshy{ 101164190Sjkoshy#ifdef __FreeBSD__ 102164190Sjkoshy int i, pri, pri2, nic; 103164190Sjkoshy#else 104164190Sjkoshy int i, pri, nic; 105164190Sjkoshy#endif 106164190Sjkoshy pid_t pid; 107164190Sjkoshy int sta; 108164190Sjkoshy 109164190Sjkoshy for (i = 0; i <= 20; i++) { 110164190Sjkoshy 111164190Sjkoshy nic = nice(i); 112164190Sjkoshy ATF_REQUIRE(nic != -1); 113164190Sjkoshy 114164190Sjkoshy errno = 0; 115164190Sjkoshy pri = getpriority(PRIO_PROCESS, 0); 116164190Sjkoshy ATF_REQUIRE(errno == 0); 117164190Sjkoshy 118164190Sjkoshy#ifdef __NetBSD__ 119164190Sjkoshy if (nic != pri) 120164190Sjkoshy atf_tc_fail("nice(3) and getpriority(2) conflict"); 121164190Sjkoshy#endif 122164190Sjkoshy 123164190Sjkoshy /* 124164190Sjkoshy * Also verify that the nice(3) values 125164190Sjkoshy * are inherited by child processes. 126164190Sjkoshy */ 127164190Sjkoshy pid = fork(); 128164190Sjkoshy ATF_REQUIRE(pid >= 0); 129164190Sjkoshy 130164190Sjkoshy if (pid == 0) { 131164190Sjkoshy 132164190Sjkoshy errno = 0; 133164190Sjkoshy#ifdef __FreeBSD__ 134164190Sjkoshy pri = getpriority(PRIO_PROCESS, 0); 135164190Sjkoshy#else 136164190Sjkoshy pri2 = getpriority(PRIO_PROCESS, 0); 137164190Sjkoshy#endif 138164190Sjkoshy ATF_REQUIRE(errno == 0); 139164190Sjkoshy 140164190Sjkoshy#ifdef __FreeBSD__ 141164190Sjkoshy if (pri != pri2) 142164190Sjkoshy#else 143164190Sjkoshy if (nic != pri) 144164190Sjkoshy#endif 145164190Sjkoshy _exit(EXIT_FAILURE); 146164190Sjkoshy 147164190Sjkoshy _exit(EXIT_SUCCESS); 148164190Sjkoshy } 149164190Sjkoshy 150164190Sjkoshy (void)wait(&sta); 151164190Sjkoshy 152164190Sjkoshy if (WIFEXITED(sta) == 0 || WEXITSTATUS(sta) != EXIT_SUCCESS) 153164190Sjkoshy atf_tc_fail("nice(3) value was not inherited"); 154164190Sjkoshy } 155164190Sjkoshy} 156164190Sjkoshy 157164190SjkoshyATF_TC(nice_root); 158164190SjkoshyATF_TC_HEAD(nice_root, tc) 159164190Sjkoshy{ 160164190Sjkoshy atf_tc_set_md_var(tc, "descr", "Test that nice(3) works"); 161164190Sjkoshy atf_tc_set_md_var(tc, "require.user", "root"); 162164190Sjkoshy} 163164190Sjkoshy 164164190SjkoshyATF_TC_BODY(nice_root, tc) 165164190Sjkoshy{ 166164190Sjkoshy int i; 167189721Sobrien 168164190Sjkoshy for (i = -20; i <= 20; i++) { 169164190Sjkoshy 170164190Sjkoshy ATF_REQUIRE(nice(i) != -1); 171164190Sjkoshy } 172164190Sjkoshy} 173164190Sjkoshy 174164190SjkoshyATF_TC(nice_thread); 175164190SjkoshyATF_TC_HEAD(nice_thread, tc) 176164225Sjkoshy{ 177164190Sjkoshy atf_tc_set_md_var(tc, "descr", "Test nice(3) with threads"); 178164190Sjkoshy} 179165317Sjkoshy 180ATF_TC_BODY(nice_thread, tc) 181{ 182 pthread_t tid[5]; 183#ifdef __FreeBSD__ 184 int pri, rv, val; 185#else 186 int rv, val; 187#endif 188 size_t i; 189 190 /* 191 * Test that the scheduling priority is 192 * propagated to all system scope threads. 193 */ 194 for (i = 0; i < __arraycount(tid); i++) { 195 196 val = nice(i); 197 ATF_REQUIRE(val != -1); 198 199#ifdef __FreeBSD__ 200 pri = getpriority(PRIO_PROCESS, 0); 201 rv = pthread_create(&tid[i], NULL, threadfunc, &pri); 202#else 203 rv = pthread_create(&tid[i], NULL, threadfunc, &val); 204#endif 205 ATF_REQUIRE(rv == 0); 206 207 rv = pthread_join(tid[i], NULL); 208 ATF_REQUIRE(rv == 0); 209 } 210} 211 212ATF_TP_ADD_TCS(tp) 213{ 214 215 ATF_TP_ADD_TC(tp, nice_err); 216 ATF_TP_ADD_TC(tp, nice_priority); 217 ATF_TP_ADD_TC(tp, nice_root); 218 ATF_TP_ADD_TC(tp, nice_thread); 219 220 return atf_no_error(); 221} 222