profil01.c revision c57fba5535abf457e33dd7a986b6c512d95cdef6
1/*
2 *
3 *   Copyright (c) International Business Machines  Corp., 2002
4 *
5 *   This program is free software;  you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation; either version 2 of the License, or
8 *   (at your option) any later version.
9 *
10 *   This program is distributed in the hope that it will be useful,
11 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13 *   the GNU General Public License for more details.
14 *
15 *   You should have received a copy of the GNU General Public License
16 *   along with this program;  if not, write to the Free Software
17 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/* 01/02/2003	Port to LTP avenkat@us.ibm.com */
21/* 06/30/2001	Port to Linux	nsharoff@us.ibm.com */
22
23/*
24 * NAME
25 *	profil1.c  -- test profil procedure
26 *
27 * CALLS
28 *	profil(2), alarm(2), signal(2)
29 *
30 * ALGORITHM
31 *	Set up a profiling buffer, turn profiling on, set a timer for
32 *	cpu time, spin the pc and wait for timer to go off.
33 *	The profiling buffer should contain some info, highly concentrated.
34 *	We just do a "looks reasonable" check.
35 *
36 * RESTRICTIONS
37 */
38
39#ifndef _GNU_SOURCE
40#define _GNU_SOURCE 1
41#endif
42
43#include <features.h>
44#include <stdio.h>
45#include <signal.h>
46#include <limits.h>
47#include <stdlib.h>
48#include <unistd.h>
49#include <errno.h>
50#include <sys/types.h>
51#include <sys/wait.h>
52#include "test.h"
53#include "usctest.h"
54
55char *TCID = "profil01";
56
57#ifndef __UCLIBC__
58
59#ifdef __arm__
60#define ADDRESS_OFFSET 0x8000
61#else
62#define ADDRESS_OFFSET 0
63#endif
64
65#define FAILED 0
66#define PASSED 1
67
68#define P_TIME		10	/* profile for this many  seconds */
69
70extern int etext;
71
72volatile int t_flag;
73
74//char progname[]= "profil1()";
75
76/*****	LTP Port	*****/
77int local_flag = PASSED;
78int block_number;
79FILE *temp;
80int TST_TOTAL = 1;
81struct sigaction sigptr;
82
83int anyfail();
84int blenter();
85int blexit();
86void setup();
87void terror();
88void fail_exit();
89/*****	**	**	*****/
90
91u_short *pbuf;
92int stuff[11];
93int loops_completed;
94int ucount, scount;
95
96/*--------------------------------------------------------------*/
97int main(int argc, char *argv[])
98{
99	register int i;
100	int count, loc;
101	long int bsize;
102	void alrm();
103#ifdef __mips__
104#if _MIPS_SIM == _MIPS_SIM_ABI64
105	extern long int __start;
106	long int lotext = (long int)&__start;
107#else
108	extern int __start;
109	int lotext = (int)&__start;
110#endif
111#elif defined(__powerpc64__)
112	extern long int _start;
113	long int *lotextptr = (long *)&_start;
114	long int lotext = *lotextptr;
115#elif __WORDSIZE == 64
116	extern long int _start;
117	long int lotext = (long)&_start;
118#else
119	extern int _start;
120	int lotext = (int)&_start;
121#endif
122
123	bsize = (long int)&etext;
124	bsize -= lotext & ~4096;
125
126	count = loc = 0;
127
128	setup();		/* temp file is now open        */
129	/*
130	   if ((sigset(SIGALRM, alrm)) == SIG_ERR) {
131	   fprintf(temp,"signal failed. errno = %d\n",errno);
132	   fail_exit();
133	   } */
134	sigptr.sa_handler = (void (*)(int signal))alrm;
135	sigfillset(&sigptr.sa_mask);
136	sigptr.sa_flags = 0;
137	sigaddset(&sigptr.sa_mask, SIGALRM);
138	if (sigaction(SIGALRM, &sigptr, NULL) == -1) {
139		fprintf(temp, "Signal SIGALRM failed, errno = %d \n", errno);
140		fail_exit();
141	}
142
143/*--------------------------------------------------------------*/
144	blenter();
145
146	if ((pbuf =
147	     (u_short *) malloc(bsize * (sizeof(u_short)))) == (u_short *) 0) {
148		fprintf(temp, "\tcannot malloc buffer.\n");
149		fail_exit();
150	}
151
152	for (i = 0; i < bsize; i++)
153		pbuf[i] = 0;
154
155	if (profil(pbuf, bsize, ADDRESS_OFFSET, 0x10000)) {
156		fprintf(temp, "\tprofile (on) failed, errno = %d\n", errno);
157		fail_exit();
158	}
159
160	/*
161	 * Set timer.
162	 * Code will just loop in small area of text.
163	 */
164
165	alarm(P_TIME);
166
167	while (!t_flag) {
168		stuff[0] = 1;
169		stuff[1] = 1;
170		stuff[2] = 1;
171		stuff[3] = 1;
172		stuff[4] = 1;
173		stuff[5] = 1;
174		stuff[6] = 1;
175		stuff[7] = 1;
176		stuff[8] = 1;
177		stuff[9] = 1;
178		stuff[10] = 1;
179		loops_completed++;
180	}
181
182	if (profil(pbuf, bsize, ADDRESS_OFFSET, 0)) {
183		fprintf(temp, "\tprofile (off) failed, errno = %d\n", errno);
184		fail_exit();
185	}
186
187	blexit();
188/*--------------------------------------------------------------*/
189	blenter();
190
191	for (i = 0; i < bsize; i++) {
192		count += pbuf[i];
193		if (pbuf[i])
194			loc++;
195	}
196	ucount = count;
197
198	blexit();
199/*--------------------------------------------------------------*/
200	blenter();
201
202	if ((sigset(SIGCLD, SIG_IGN)) == SIG_ERR) {
203		fprintf(temp, "signal failed. errno = %d\n", errno);
204		fail_exit();
205	}
206	t_flag = 0;
207	setpgrp();
208	for (i = 0; i < bsize; i++)
209		pbuf[i] = 0;
210
211	if (profil(pbuf, bsize, ADDRESS_OFFSET, 0x10000)) {
212		fprintf(temp, "\tprofile (on) failed, errno = %d\n", errno);
213		fail_exit();
214	}
215
216	/*
217	 * Set timer. This loop will spend a lot of time in system code
218	 * (searching though proc table) that won't add to our buffer
219	 * since the pc isn't in our code.
220	 */
221
222	alarm(P_TIME);
223
224	while (!t_flag) {
225		kill(getpid(), SIGCLD);
226	}
227
228	if (profil(pbuf, bsize, ADDRESS_OFFSET, 0)) {
229		fprintf(temp, "\tprofile (off) failed, errno = %d\n", errno);
230		fail_exit();
231	}
232
233	count = 0;
234	for (i = 0; i < bsize; i++) {
235		count += pbuf[i];
236		if (pbuf[i])
237			loc++;
238	}
239	scount = count;
240
241	if (scount > ucount) {
242		fprintf(temp, "\tUnexpected profiling results.\n");
243		fprintf(temp, "\tExpected second value to be less.\n");
244		local_flag = FAILED;
245	}
246
247	blexit();
248/*--------------------------------------------------------------*/
249	anyfail();		/* THIS CALL DOES NOT RETURN - EXITS!!  */
250	tst_exit();
251}
252
253/*--------------------------------------------------------------*/
254
255void alrm(void)
256{
257	t_flag++;
258}
259
260/*****	LTP Port	*****/
261int anyfail(void)
262{
263	(local_flag == FAILED) ? tst_resm(TFAIL,
264					  "Test failed") : tst_resm(TPASS,
265								    "Test passed");
266	tst_exit();
267	return 0;
268}
269
270void setup(void)
271{
272	temp = stderr;
273}
274
275int blenter(void)
276{
277	//tst_resm(TINFO, "Enter block %d", block_number);
278	local_flag = PASSED;
279	return 0;
280}
281
282int blexit(void)
283{
284	//tst_resm(TINFO, "Exitng test");
285	(local_flag == FAILED) ? tst_resm(TFAIL,
286					  "Test failed") : tst_resm(TPASS,
287								    "Test passed");
288	return 0;
289}
290
291void terror(char *message)
292{
293	tst_resm(TBROK, "Reason: %s:%s", message, strerror(errno));
294}
295
296void fail_exit(void)
297{
298	local_flag = FAILED;
299	anyfail();
300
301}
302
303/*****	**	**	*****/
304
305#else
306int main(void)
307{
308	/* uClibc does not have profiling support */
309	tst_exit();
310}
311#endif
312