1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci * Copyright (c) 2004, Bull S.A..  All rights reserved.
3f08c3bdfSopenharmony_ci * Created by: Sebastien Decugis
4f08c3bdfSopenharmony_ci
5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify it
6f08c3bdfSopenharmony_ci * under the terms of version 2 of the GNU General Public License as
7f08c3bdfSopenharmony_ci * published by the Free Software Foundation.
8f08c3bdfSopenharmony_ci *
9f08c3bdfSopenharmony_ci * This program is distributed in the hope that it would be useful, but
10f08c3bdfSopenharmony_ci * WITHOUT ANY WARRANTY; without even the implied warranty of
11f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12f08c3bdfSopenharmony_ci *
13f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License along
14f08c3bdfSopenharmony_ci * with this program; if not, write the Free Software Foundation, Inc.,
15f08c3bdfSopenharmony_ci * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16f08c3bdfSopenharmony_ci
17f08c3bdfSopenharmony_ci */
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_ci/*
20f08c3bdfSopenharmony_ci * The purpose of this file is to provide a monitor process
21f08c3bdfSopenharmony_ci * for the stress/threads/ * / *.c testcases in the OPTS.
22f08c3bdfSopenharmony_ci *
23f08c3bdfSopenharmony_ci * The goal is:
24f08c3bdfSopenharmony_ci * -> if the testcase returns, the monitor returns the error code.
25f08c3bdfSopenharmony_ci * -> after a specified timeout, the monitor let the stress test terminate
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_ci * This allows for the stress tests to be run in an automatic maneer
28f08c3bdfSopenharmony_ci * with a script such as:
29f08c3bdfSopenharmony_ci#!/bin/sh
30f08c3bdfSopenharmony_ci
31f08c3bdfSopenharmony_ci#monitor the system
32f08c3bdfSopenharmony_civmstat -n 120 180 >monitor.txt 2>&1 &
33f08c3bdfSopenharmony_ci
34f08c3bdfSopenharmony_ci#run the tests
35f08c3bdfSopenharmony_cifor TS in `ls -1 *.c`;
36f08c3bdfSopenharmony_cido <compile $TS>;
37f08c3bdfSopenharmony_ciif [ $? -eq 0 ];
38f08c3bdfSopenharmony_cithen <run in background:>
39f08c3bdfSopenharmony_ci     helper 6 $TS.exe &
40f08c3bdfSopenharmony_cifi
41f08c3bdfSopenharmony_cidone
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_ci#wait for the end
44f08c3bdfSopenharmony_ciwhile [ "`ps -e | grep helper`" ];
45f08c3bdfSopenharmony_cido sleep 30;
46f08c3bdfSopenharmony_cidone
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_ci*/
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci#include <pthread.h>
51f08c3bdfSopenharmony_ci#include <stdio.h>
52f08c3bdfSopenharmony_ci#include <stdlib.h>
53f08c3bdfSopenharmony_ci#include <unistd.h>
54f08c3bdfSopenharmony_ci#include <signal.h>
55f08c3bdfSopenharmony_ci#include <sys/wait.h>
56f08c3bdfSopenharmony_ci#include <assert.h>
57f08c3bdfSopenharmony_ci#include <time.h>
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_cistatic pid_t child;
60f08c3bdfSopenharmony_cistatic int timeout;
61f08c3bdfSopenharmony_ci
62f08c3bdfSopenharmony_ci/* Note that there could be a race between
63f08c3bdfSopenharmony_cithe moment the stress test terminates and
64f08c3bdfSopenharmony_ciwhen the timeout expires. As this is highly
65f08c3bdfSopenharmony_ciimprobable, we don't care... */
66f08c3bdfSopenharmony_ci
67f08c3bdfSopenharmony_cistatic void *timer(void *arg)
68f08c3bdfSopenharmony_ci{
69f08c3bdfSopenharmony_ci	int ret = 0;
70f08c3bdfSopenharmony_ci
71f08c3bdfSopenharmony_ci	unsigned remaining = timeout * 3600;
72f08c3bdfSopenharmony_ci	do {
73f08c3bdfSopenharmony_ci		remaining = sleep(remaining);
74f08c3bdfSopenharmony_ci	} while (remaining);
75f08c3bdfSopenharmony_ci	ret = kill(child, SIGUSR1);
76f08c3bdfSopenharmony_ci	if (ret != 0) {
77f08c3bdfSopenharmony_ci		perror("Failed to kill the stress test");
78f08c3bdfSopenharmony_ci		exit(2);
79f08c3bdfSopenharmony_ci	}
80f08c3bdfSopenharmony_ci
81f08c3bdfSopenharmony_ci	return NULL;
82f08c3bdfSopenharmony_ci}
83f08c3bdfSopenharmony_ci
84f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
85f08c3bdfSopenharmony_ci{
86f08c3bdfSopenharmony_ci	int ret;
87f08c3bdfSopenharmony_ci	pthread_t th;
88f08c3bdfSopenharmony_ci	pid_t chk;
89f08c3bdfSopenharmony_ci	int status;
90f08c3bdfSopenharmony_ci	char *ts = "[??:??:??]";
91f08c3bdfSopenharmony_ci	struct tm *now;
92f08c3bdfSopenharmony_ci	time_t nw;
93f08c3bdfSopenharmony_ci
94f08c3bdfSopenharmony_ci	/* check args */
95f08c3bdfSopenharmony_ci	if (argc < 3) {
96f08c3bdfSopenharmony_ci		printf("\nUsage: \n");
97f08c3bdfSopenharmony_ci		printf("  $ %s n exe arglist\n", argv[0]);
98f08c3bdfSopenharmony_ci		printf("\nWhere:\n");
99f08c3bdfSopenharmony_ci		printf("  n       is the timeout duration in hours,\n");
100f08c3bdfSopenharmony_ci		printf("  exe     is the stress test executable to monitor,\n");
101f08c3bdfSopenharmony_ci		printf
102f08c3bdfSopenharmony_ci		    ("  arglist is the arguments to be passed to executable.\n\n");
103f08c3bdfSopenharmony_ci		return 2;
104f08c3bdfSopenharmony_ci	}
105f08c3bdfSopenharmony_ci
106f08c3bdfSopenharmony_ci	timeout = atoi(argv[1]);
107f08c3bdfSopenharmony_ci	if (timeout < 1) {
108f08c3bdfSopenharmony_ci		fprintf(stderr,
109f08c3bdfSopenharmony_ci			"Invalid timeout value \"%s\". Timeout must be a positive integer.\n",
110f08c3bdfSopenharmony_ci			argv[1]);
111f08c3bdfSopenharmony_ci		return 2;
112f08c3bdfSopenharmony_ci	}
113f08c3bdfSopenharmony_ci
114f08c3bdfSopenharmony_ci	/* create the timer thread */
115f08c3bdfSopenharmony_ci	ret = pthread_create(&th, NULL, timer, NULL);
116f08c3bdfSopenharmony_ci	if (ret != 0) {
117f08c3bdfSopenharmony_ci		perror("Failed to create the timeout thread\n");
118f08c3bdfSopenharmony_ci		return 2;
119f08c3bdfSopenharmony_ci	}
120f08c3bdfSopenharmony_ci
121f08c3bdfSopenharmony_ci	/* Create the new process for the stress test */
122f08c3bdfSopenharmony_ci	child = fork();
123f08c3bdfSopenharmony_ci
124f08c3bdfSopenharmony_ci	if (child == (pid_t) - 1) {
125f08c3bdfSopenharmony_ci		perror("Failed to create a new process");
126f08c3bdfSopenharmony_ci		exit(2);
127f08c3bdfSopenharmony_ci	}
128f08c3bdfSopenharmony_ci
129f08c3bdfSopenharmony_ci	/* The child process executes the test */
130f08c3bdfSopenharmony_ci	if (child == (pid_t) 0) {
131f08c3bdfSopenharmony_ci
132f08c3bdfSopenharmony_ci		/* Execute the command */
133f08c3bdfSopenharmony_ci		ret = execvp(argv[2], &argv[2]);
134f08c3bdfSopenharmony_ci		if (ret == -1) {
135f08c3bdfSopenharmony_ci			/* Application was not launched */
136f08c3bdfSopenharmony_ci			perror("Unable to run child application");
137f08c3bdfSopenharmony_ci			return 2;
138f08c3bdfSopenharmony_ci		}
139f08c3bdfSopenharmony_ci		assert(0);
140f08c3bdfSopenharmony_ci		perror("Should not see me");
141f08c3bdfSopenharmony_ci		return 2;
142f08c3bdfSopenharmony_ci	}
143f08c3bdfSopenharmony_ci
144f08c3bdfSopenharmony_ci	/* The parent: */
145f08c3bdfSopenharmony_ci
146f08c3bdfSopenharmony_ci	/* wait for the child process to terminate */
147f08c3bdfSopenharmony_ci	chk = waitpid(child, &status, 0);
148f08c3bdfSopenharmony_ci	if (chk != child) {
149f08c3bdfSopenharmony_ci		perror("Got the wrong process image status");
150f08c3bdfSopenharmony_ci		return 2;
151f08c3bdfSopenharmony_ci	}
152f08c3bdfSopenharmony_ci
153f08c3bdfSopenharmony_ci	/* Cancel the timer thread in case the process returned by itself */
154f08c3bdfSopenharmony_ci	(void)pthread_cancel(th);
155f08c3bdfSopenharmony_ci
156f08c3bdfSopenharmony_ci	ret = pthread_join(th, NULL);
157f08c3bdfSopenharmony_ci	if (ret != 0) {
158f08c3bdfSopenharmony_ci		perror("Unable to join the timer thread");
159f08c3bdfSopenharmony_ci		return 2;
160f08c3bdfSopenharmony_ci	}
161f08c3bdfSopenharmony_ci
162f08c3bdfSopenharmony_ci	/* return */
163f08c3bdfSopenharmony_ci	nw = time(NULL);
164f08c3bdfSopenharmony_ci	now = localtime(&nw);
165f08c3bdfSopenharmony_ci	if (now == NULL)
166f08c3bdfSopenharmony_ci		printf(ts);
167f08c3bdfSopenharmony_ci	else
168f08c3bdfSopenharmony_ci		printf("[%2.2d:%2.2d:%2.2d]\n", now->tm_hour, now->tm_min,
169f08c3bdfSopenharmony_ci		       now->tm_sec);
170f08c3bdfSopenharmony_ci	if (!WIFEXITED(status)) {
171f08c3bdfSopenharmony_ci		printf("The stress sample did not exit\n");
172f08c3bdfSopenharmony_ci		if (WIFSIGNALED(status)) {
173f08c3bdfSopenharmony_ci			printf("It was killed with signal %i\n",
174f08c3bdfSopenharmony_ci			       WTERMSIG(status));
175f08c3bdfSopenharmony_ci		} else {
176f08c3bdfSopenharmony_ci			printf("and it was not killed...\n");
177f08c3bdfSopenharmony_ci		}
178f08c3bdfSopenharmony_ci		exit(1);
179f08c3bdfSopenharmony_ci	}
180f08c3bdfSopenharmony_ci	if (WEXITSTATUS(status) == 0) {
181f08c3bdfSopenharmony_ci		printf("Test %s PASSED\n", argv[2]);
182f08c3bdfSopenharmony_ci	} else {
183f08c3bdfSopenharmony_ci		printf("Test %s: returned %d\n", argv[2], WEXITSTATUS(status));
184f08c3bdfSopenharmony_ci	}
185f08c3bdfSopenharmony_ci	exit(WEXITSTATUS(status));
186f08c3bdfSopenharmony_ci}
187