1/*
2* Copyright (c) 2004, 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., 59
15* Temple Place - Suite 330, Boston MA 02111-1307, USA.
16
17
18* This sample test aims to check the following assertion:
19*
20* tms_{,c}{u,s}time values are set to 0 in the child process.
21
22
23* The steps are:
24* -> Work for 1 second and save the tms information
25* -> fork
26* -> Check that the child has tms values less than the saved tms.
27* -> join the child process
28* -> check tms_c{u,s}time are not 0 anymore.
29
30* The test fails if one of the described checking fails.
31
32*/
33
34
35/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
36#define _POSIX_C_SOURCE 200112L
37
38/********************************************************************************************/
39/****************************** standard includes *****************************************/
40/********************************************************************************************/
41#include <pthread.h>
42 #include <stdarg.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48#include <sys/wait.h>
49 #include <errno.h>
50
51#include <sys/times.h>
52
53/********************************************************************************************/
54/******************************   Test framework   *****************************************/
55/********************************************************************************************/
56#include "testfrmw.h"
57 #include "testfrmw.c"
58/* This header is responsible for defining the following macros:
59 * UNRESOLVED(ret, descr);
60 *    where descr is a description of the error and ret is an int (error code for example)
61 * FAILED(descr);
62 *    where descr is a short text saying why the test has failed.
63 * PASSED();
64 *    No parameter.
65 *
66 * Both three macros shall terminate the calling process.
67 * The testcase shall not terminate in any other maneer.
68 *
69 * The other file defines the functions
70 * void output_init()
71 * void output(char * string, ...)
72 *
73 * Those may be used to output information.
74 */
75
76/********************************************************************************************/
77/********************************** Configuration ******************************************/
78/********************************************************************************************/
79#ifndef VERBOSE
80#define VERBOSE 1
81#endif
82
83/********************************************************************************************/
84/***********************************    Test case   *****************************************/
85/********************************************************************************************/
86
87/* The main test function. */
88int main( int argc, char * argv[] )
89{
90	int status;
91	pid_t child, ctl;
92
93	clock_t st_time, cur_time;
94
95	struct tms ini_tms, parent_tms, child_tms;
96
97	/* Initialize output */
98	output_init();
99
100	/* Initialize first times */
101	st_time = times( &ini_tms );
102
103	if ( st_time == ( clock_t ) - 1 )
104	{
105		UNRESOLVED( errno, "times failed" );
106	}
107
108	if ( ( ini_tms.tms_cutime != 0 ) || ( ini_tms.tms_cstime != 0 ) )
109	{
110		FAILED( "The process is created with non-zero tms_cutime or tms_cstime" );
111	}
112
113#if VERBOSE > 1
114	output( "Starting loop...\n" );
115
116#endif
117
118	/* Busy loop for some times */
119	do
120	{
121		cur_time = times( &parent_tms );
122
123		if ( cur_time == ( clock_t ) - 1 )
124		{
125			UNRESOLVED( errno, "times failed" );
126		}
127	}
128	while ( ( cur_time - st_time ) < sysconf( _SC_CLK_TCK ) );
129
130#if VERBOSE > 1
131
132	output( "Busy loop terminated\n" );
133
134	output( " Real time: %ld, User Time %ld, System Time %ld, Ticks per sec %ld\n",
135	        ( long ) ( cur_time - st_time ),
136	        ( long ) ( parent_tms.tms_utime - ini_tms.tms_utime ),
137	        ( long ) ( parent_tms.tms_stime - ini_tms.tms_stime ),
138	        sysconf( _SC_CLK_TCK ) );
139
140#endif
141
142	/* Create the child */
143	child = fork();
144
145	if ( child == ( pid_t ) - 1 )
146	{
147		UNRESOLVED( errno, "Failed to fork" );
148	}
149
150	/* child */
151	if ( child == ( pid_t ) 0 )
152	{
153
154		cur_time = times( &child_tms );
155
156		if ( cur_time == ( clock_t ) - 1 )
157		{
158			UNRESOLVED( errno, "times failed" );
159		}
160
161		if ( child_tms.tms_utime + child_tms.tms_stime >= sysconf( _SC_CLK_TCK ) )
162		{
163			FAILED( "The tms struct was not reset during fork() operation" );
164		}
165
166		do
167		{
168			cur_time = times( &child_tms );
169
170			if ( cur_time == ( clock_t ) - 1 )
171			{
172				UNRESOLVED( errno, "times failed" );
173			}
174		}
175		while ( ( child_tms.tms_utime + child_tms.tms_stime ) <= 0 );
176
177		/* We're done */
178		exit( PTS_PASS );
179	}
180
181	/* Parent joins the child */
182	ctl = waitpid( child, &status, 0 );
183
184	if ( ctl != child )
185	{
186		UNRESOLVED( errno, "Waitpid returned the wrong PID" )
187		;
188	}
189
190	if ( ( !WIFEXITED( status ) ) || ( WEXITSTATUS( status ) != PTS_PASS ) )
191	{
192		FAILED( "Child exited abnormally" )
193		;
194	}
195
196	/* Check the children times were reported as expected */
197	cur_time = times( &parent_tms );
198
199#if VERBOSE > 1
200
201	output( "Child joined\n" );
202
203	output( " Real time: %ld,\n"
204	        "  User Time %ld, System Time %ld,\n"
205	        "  Child User Time %ld, Child System Time %ld\n",
206	        ( long ) ( cur_time - st_time ),
207	        ( long ) ( parent_tms.tms_utime - ini_tms.tms_utime ),
208	        ( long ) ( parent_tms.tms_stime - ini_tms.tms_stime ),
209	        ( long ) ( parent_tms.tms_cutime - ini_tms.tms_cutime ),
210	        ( long ) ( parent_tms.tms_cstime - ini_tms.tms_cstime )
211	      );
212
213#endif
214
215	if ( cur_time == ( clock_t ) - 1 )
216	{
217		UNRESOLVED( errno, "times failed" );
218	}
219
220	if ( ( parent_tms.tms_cutime == 0 ) && ( parent_tms.tms_cstime == 0 ) )
221	{
222		FAILED( "The process is created with non-zero tms_cutime or tms_cstime" );
223	}
224
225
226	/* Test passed */
227#if VERBOSE > 0
228
229	output( "Test passed\n" );
230
231#endif
232
233	PASSED;
234}
235
236
237