1/*
2* Copyright (c) 2005, Bull S.A..  All rights reserved.
3* Created by: Sebastien Decugis
4
5* This program is free software; you can redistribute it and/or modify it
6* under the terms of version 2 of the GNU General Public License as
7* published by the Free Software Foundation.
8*
9* This program is distributed in the hope that it would be useful, but
10* WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*
13* You should have received a copy of the GNU General Public License along
14* with this program; if not, write the Free Software Foundation, Inc.,
15* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
17* This sample test aims to check the following assertion:
18*
19* If the function fails, the policy and parameter of the target thread
20* shall not be modified.
21
22* The steps are:
23* -> Create a new thread
24* -> Change its priority to a known valid value.
25* -> Change its priority to an invalid value.
26
27* The test fails if the priority is changed and an error returned.
28*/
29
30/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
31#define _POSIX_C_SOURCE 200112L
32
33/******************************************************************************/
34/*********************** standard includes ************************************/
35/******************************************************************************/
36#include <pthread.h>
37#include <stdarg.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <string.h>
41#include <unistd.h>
42
43#include <sched.h>
44#include <errno.h>
45
46/******************************************************************************/
47/***********************   Test framework   ***********************************/
48/******************************************************************************/
49#include "../testfrmw/testfrmw.h"
50#include "../testfrmw/testfrmw.c"
51/* This header is responsible for defining the following macros:
52 * UNRESOLVED(ret, descr);
53 *    where descr is a description of the error and ret is an int
54 *   (error code for example)
55 * FAILED(descr);
56 *    where descr is a short text saying why the test has failed.
57 * PASSED();
58 *    No parameter.
59 *
60 * Both three macros shall terminate the calling process.
61 * The testcase shall not terminate in any other maneer.
62 *
63 * The other file defines the functions
64 * void output_init()
65 * void output(char * string, ...)
66 *
67 * Those may be used to output information.
68 */
69
70/******************************************************************************/
71/***************************** Configuration **********************************/
72/******************************************************************************/
73#ifndef VERBOSE
74#define VERBOSE 1
75#endif
76
77/******************************************************************************/
78/*****************************    Test case   *********************************/
79/******************************************************************************/
80
81/* This function checks the thread policy & priority */
82void check_param(pthread_t thread, int policy, int priority)
83{
84	int ret = 0;
85
86	int t_pol;
87
88	struct sched_param t_parm;
89
90	/* Check the priority is valid */
91
92	if (priority == -1) {
93		UNRESOLVED(errno, "Wrong priority value");
94	}
95
96	/* Get the thread's parameters */
97	ret = pthread_getschedparam(thread, &t_pol, &t_parm);
98
99	if (ret != 0) {
100		UNRESOLVED(ret, "Failed to get thread's parameters");
101	}
102
103	if (t_pol != policy) {
104		FAILED("The thread's policy is not as expected");
105	}
106
107	if (t_parm.sched_priority != priority) {
108		FAILED("The thread's priority is not as expected");
109	}
110}
111
112/* thread function */
113void *threaded(void *arg)
114{
115	int ret = 0;
116
117	struct sched_param sp;
118
119	/* Set priority to a known value */
120	sp.sched_priority = sched_get_priority_max(SCHED_RR);
121
122	ret = pthread_setschedparam(pthread_self(), SCHED_RR, &sp);
123
124	if (ret != 0) {
125		UNRESOLVED(ret,
126			   "Failed to set thread policy -- need to be root?");
127	}
128
129	/* check the thread attributes have been applied
130	   (we only check what is reported, not the real behavior)
131	 */
132	check_param(pthread_self(), SCHED_RR, sp.sched_priority);
133
134	/* Now set the priority to an invalid value. */
135	sp.sched_priority++;
136
137	ret = pthread_setschedparam(pthread_self(), SCHED_RR, &sp);
138
139	if (ret != 0) {
140		/* check the thread attributes have been applied
141		   (we only check what is reported, not the real behavior)
142		 */
143		check_param(pthread_self(), SCHED_RR, sp.sched_priority - 1);
144#if VERBOSE > 0
145		output
146		    ("Setting to a wrong priority failed with error %d (%s).\n",
147		     ret, strerror(ret));
148	} else {
149		output("UNTESTED: setting to max prio + 1 did not fail.\n");
150#endif
151
152	}
153
154	return NULL;
155}
156
157/* The main test function. */
158int main(void)
159{
160	int ret = 0;
161	pthread_t child;
162
163	/* Initialize output routine */
164	output_init();
165
166	/* Create the controler thread */
167	ret = pthread_create(&child, NULL, threaded, NULL);
168
169	if (ret != 0) {
170		UNRESOLVED(ret, "thread creation failed");
171	}
172
173	ret = pthread_join(child, NULL);
174
175	if (ret != 0) {
176		UNRESOLVED(ret, "Failed to join the thread");
177	}
178#if VERBOSE > 0
179	output("Test PASSED.\n");
180
181#endif
182
183	PASSED;
184}
185