1f08c3bdfSopenharmony_ci/*
2f08c3bdfSopenharmony_ci *
3f08c3bdfSopenharmony_ci *   Copyright (c) International Business Machines  Corp., 2001
4f08c3bdfSopenharmony_ci *
5f08c3bdfSopenharmony_ci *   This program is free software;  you can redistribute it and/or modify
6f08c3bdfSopenharmony_ci *   it under the terms of the GNU General Public License as published by
7f08c3bdfSopenharmony_ci *   the Free Software Foundation; either version 2 of the License, or
8f08c3bdfSopenharmony_ci *   (at your option) any later version.
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci *   This program is distributed in the hope that it will be useful,
11f08c3bdfSopenharmony_ci *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12f08c3bdfSopenharmony_ci *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13f08c3bdfSopenharmony_ci *   the GNU General Public License for more details.
14f08c3bdfSopenharmony_ci *
15f08c3bdfSopenharmony_ci *   You should have received a copy of the GNU General Public License
16f08c3bdfSopenharmony_ci *   along with this program;  if not, write to the Free Software
17f08c3bdfSopenharmony_ci *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18f08c3bdfSopenharmony_ci */
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_ci/*
21f08c3bdfSopenharmony_ci * FILE        : openfile.c
22f08c3bdfSopenharmony_ci * DESCRIPTION : Create files and open simultaneously
23f08c3bdfSopenharmony_ci * HISTORY:
24f08c3bdfSopenharmony_ci *   03/21/2001 Paul Larson (plars@us.ibm.com)
25f08c3bdfSopenharmony_ci *     -Ported
26f08c3bdfSopenharmony_ci *   11/01/2001 Mnaoj Iyer (manjo@austin.ibm.com)
27f08c3bdfSopenharmony_ci *     - Modified.
28f08c3bdfSopenharmony_ci *	 added #inclide <unistd.h>
29f08c3bdfSopenharmony_ci *
30f08c3bdfSopenharmony_ci */
31f08c3bdfSopenharmony_ci
32f08c3bdfSopenharmony_ci#include <pthread.h>
33f08c3bdfSopenharmony_ci#include <stdio.h>
34f08c3bdfSopenharmony_ci#include <stdlib.h>
35f08c3bdfSopenharmony_ci#include <stdint.h>
36f08c3bdfSopenharmony_ci#include <unistd.h>
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ci#include "test.h"
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_cichar *TCID = "openfile01";	/* Test program identifier.    */
41f08c3bdfSopenharmony_ciint TST_TOTAL = 1;
42f08c3bdfSopenharmony_ci
43f08c3bdfSopenharmony_ci#define MAXFILES        32768
44f08c3bdfSopenharmony_ci#define MAXTHREADS      10
45f08c3bdfSopenharmony_ci
46f08c3bdfSopenharmony_ci/* Control Structure */
47f08c3bdfSopenharmony_cistruct cb {
48f08c3bdfSopenharmony_ci	pthread_mutex_t m;
49f08c3bdfSopenharmony_ci	pthread_cond_t init_cv;
50f08c3bdfSopenharmony_ci	pthread_cond_t thr_cv;
51f08c3bdfSopenharmony_ci	int thr_sleeping;
52f08c3bdfSopenharmony_ci} c;
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_ci/* Global Variables */
55f08c3bdfSopenharmony_ciint numthreads = 10, numfiles = 10;
56f08c3bdfSopenharmony_ciint debug = 0;
57f08c3bdfSopenharmony_cichar *filename = "FILETOOPEN";
58f08c3bdfSopenharmony_ci
59f08c3bdfSopenharmony_civoid setup(void)
60f08c3bdfSopenharmony_ci{
61f08c3bdfSopenharmony_ci	tst_tmpdir();
62f08c3bdfSopenharmony_ci}
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_civoid cleanup(void)
65f08c3bdfSopenharmony_ci{
66f08c3bdfSopenharmony_ci	tst_rmdir();
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci}
69f08c3bdfSopenharmony_ci
70f08c3bdfSopenharmony_ci/* Procedures */
71f08c3bdfSopenharmony_civoid *threads(void *thread_id);
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_ci/* **************************************************************************
74f08c3bdfSopenharmony_ci *                              MAIN PROCEDURE                            *
75f08c3bdfSopenharmony_ci ************************************************************************** */
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ciint main(int argc, char *argv[])
78f08c3bdfSopenharmony_ci{
79f08c3bdfSopenharmony_ci	int i, opt, badopts = 0;
80f08c3bdfSopenharmony_ci	FILE *fd;
81f08c3bdfSopenharmony_ci	pthread_t th_id;
82f08c3bdfSopenharmony_ci	char msg[80] = "";
83f08c3bdfSopenharmony_ci	extern char *optarg;
84f08c3bdfSopenharmony_ci
85f08c3bdfSopenharmony_ci	while ((opt = getopt(argc, argv, "df:t:h")) != EOF) {
86f08c3bdfSopenharmony_ci		switch ((char)opt) {
87f08c3bdfSopenharmony_ci		case 'd':
88f08c3bdfSopenharmony_ci			debug = 1;
89f08c3bdfSopenharmony_ci			break;
90f08c3bdfSopenharmony_ci		case 'f':
91f08c3bdfSopenharmony_ci			numfiles = atoi(optarg);
92f08c3bdfSopenharmony_ci			if (numfiles <= 0)
93f08c3bdfSopenharmony_ci				badopts = 1;
94f08c3bdfSopenharmony_ci			break;
95f08c3bdfSopenharmony_ci		case 't':
96f08c3bdfSopenharmony_ci			numthreads = atoi(optarg);
97f08c3bdfSopenharmony_ci			if (numthreads <= 0)
98f08c3bdfSopenharmony_ci				badopts = 1;
99f08c3bdfSopenharmony_ci			break;
100f08c3bdfSopenharmony_ci		case 'h':
101f08c3bdfSopenharmony_ci		default:
102f08c3bdfSopenharmony_ci			printf("Usage: openfile [-d] -f FILES -t THREADS\n");
103f08c3bdfSopenharmony_ci			_exit(1);
104f08c3bdfSopenharmony_ci		}
105f08c3bdfSopenharmony_ci	}
106f08c3bdfSopenharmony_ci	if (badopts) {
107f08c3bdfSopenharmony_ci		printf("Usage: openfile [-d] -f FILES -t THREADS\n");
108f08c3bdfSopenharmony_ci		_exit(1);
109f08c3bdfSopenharmony_ci	}
110f08c3bdfSopenharmony_ci
111f08c3bdfSopenharmony_ci	setup();
112f08c3bdfSopenharmony_ci
113f08c3bdfSopenharmony_ci	/* Check if numthreads is less than MAXFILES */
114f08c3bdfSopenharmony_ci	if (numfiles > MAXFILES) {
115f08c3bdfSopenharmony_ci		sprintf(msg, "%s\nCannot use %d files", msg, numfiles);
116f08c3bdfSopenharmony_ci		sprintf(msg, "%s, used %d files instead\n", msg, MAXFILES);
117f08c3bdfSopenharmony_ci		numfiles = MAXFILES;
118f08c3bdfSopenharmony_ci	}
119f08c3bdfSopenharmony_ci
120f08c3bdfSopenharmony_ci	/* Check if numthreads is less than MAXTHREADS */
121f08c3bdfSopenharmony_ci	if (numthreads > MAXTHREADS) {
122f08c3bdfSopenharmony_ci		sprintf(msg, "%s\nCannot use %d threads", msg, numthreads);
123f08c3bdfSopenharmony_ci		sprintf(msg, "%s, used %d threads instead\n", msg, MAXTHREADS);
124f08c3bdfSopenharmony_ci		numthreads = MAXTHREADS;
125f08c3bdfSopenharmony_ci	}
126f08c3bdfSopenharmony_ci
127f08c3bdfSopenharmony_ci	/* Create files */
128f08c3bdfSopenharmony_ci	if ((fd = fopen(filename, "w")) == NULL) {
129f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "Could not create file");
130f08c3bdfSopenharmony_ci		cleanup();
131f08c3bdfSopenharmony_ci	}
132f08c3bdfSopenharmony_ci
133f08c3bdfSopenharmony_ci	/* Initialize thread control variables, lock & condition */
134f08c3bdfSopenharmony_ci	pthread_mutex_init(&c.m, NULL);
135f08c3bdfSopenharmony_ci	pthread_cond_init(&c.init_cv, NULL);
136f08c3bdfSopenharmony_ci	pthread_cond_init(&c.thr_cv, NULL);
137f08c3bdfSopenharmony_ci	c.thr_sleeping = 0;
138f08c3bdfSopenharmony_ci
139f08c3bdfSopenharmony_ci	/* Grab mutex lock */
140f08c3bdfSopenharmony_ci	if (pthread_mutex_lock(&c.m)) {
141f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "failed to grab mutex lock");
142f08c3bdfSopenharmony_ci		fclose(fd);
143f08c3bdfSopenharmony_ci		unlink(filename);
144f08c3bdfSopenharmony_ci		cleanup();
145f08c3bdfSopenharmony_ci	}
146f08c3bdfSopenharmony_ci
147f08c3bdfSopenharmony_ci	printf("Creating Reading Threads\n");
148f08c3bdfSopenharmony_ci
149f08c3bdfSopenharmony_ci	/* Create threads */
150f08c3bdfSopenharmony_ci	for (i = 0; i < numthreads; i++)
151f08c3bdfSopenharmony_ci		if (pthread_create(&th_id, NULL, threads,
152f08c3bdfSopenharmony_ci				   (void *)(uintptr_t) i)) {
153f08c3bdfSopenharmony_ci			tst_resm(TFAIL,
154f08c3bdfSopenharmony_ci				 "failed creating a pthread; increase limits");
155f08c3bdfSopenharmony_ci			fclose(fd);
156f08c3bdfSopenharmony_ci			unlink(filename);
157f08c3bdfSopenharmony_ci			cleanup();
158f08c3bdfSopenharmony_ci		}
159f08c3bdfSopenharmony_ci
160f08c3bdfSopenharmony_ci	/* Sleep until all threads are created */
161f08c3bdfSopenharmony_ci	while (c.thr_sleeping != numthreads)
162f08c3bdfSopenharmony_ci		if (pthread_cond_wait(&c.init_cv, &c.m)) {
163f08c3bdfSopenharmony_ci			tst_resm(TFAIL,
164f08c3bdfSopenharmony_ci				 "error while waiting for reading threads");
165f08c3bdfSopenharmony_ci			fclose(fd);
166f08c3bdfSopenharmony_ci			unlink(filename);
167f08c3bdfSopenharmony_ci			cleanup();
168f08c3bdfSopenharmony_ci		}
169f08c3bdfSopenharmony_ci
170f08c3bdfSopenharmony_ci	/* Wake up all threads */
171f08c3bdfSopenharmony_ci	if (pthread_cond_broadcast(&c.thr_cv)) {
172f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "failed trying to wake up reading threads");
173f08c3bdfSopenharmony_ci		fclose(fd);
174f08c3bdfSopenharmony_ci		unlink(filename);
175f08c3bdfSopenharmony_ci		cleanup();
176f08c3bdfSopenharmony_ci	}
177f08c3bdfSopenharmony_ci	/* Release mutex lock */
178f08c3bdfSopenharmony_ci	if (pthread_mutex_unlock(&c.m)) {
179f08c3bdfSopenharmony_ci		tst_resm(TFAIL, "failed to release mutex lock");
180f08c3bdfSopenharmony_ci		fclose(fd);
181f08c3bdfSopenharmony_ci		unlink(filename);
182f08c3bdfSopenharmony_ci		cleanup();
183f08c3bdfSopenharmony_ci	}
184f08c3bdfSopenharmony_ci
185f08c3bdfSopenharmony_ci	tst_resm(TPASS, "Threads are done reading");
186f08c3bdfSopenharmony_ci
187f08c3bdfSopenharmony_ci	fclose(fd);
188f08c3bdfSopenharmony_ci	unlink(filename);
189f08c3bdfSopenharmony_ci	cleanup();
190f08c3bdfSopenharmony_ci	_exit(0);
191f08c3bdfSopenharmony_ci}
192f08c3bdfSopenharmony_ci
193f08c3bdfSopenharmony_ci/* **************************************************************************
194f08c3bdfSopenharmony_ci *				OTHER PROCEDURES			    *
195f08c3bdfSopenharmony_ci ************************************************************************** */
196f08c3bdfSopenharmony_ci
197f08c3bdfSopenharmony_civoid close_files(FILE * fd_list[], int len)
198f08c3bdfSopenharmony_ci{
199f08c3bdfSopenharmony_ci	int i;
200f08c3bdfSopenharmony_ci	for (i = 0; i < len; i++) {
201f08c3bdfSopenharmony_ci		fclose(fd_list[i]);
202f08c3bdfSopenharmony_ci	}
203f08c3bdfSopenharmony_ci}
204f08c3bdfSopenharmony_ci
205f08c3bdfSopenharmony_ci/* threads: Each thread opens the files specified */
206f08c3bdfSopenharmony_civoid *threads(void *thread_id_)
207f08c3bdfSopenharmony_ci{
208f08c3bdfSopenharmony_ci	int thread_id = (uintptr_t) thread_id_;
209f08c3bdfSopenharmony_ci	char errmsg[80];
210f08c3bdfSopenharmony_ci	FILE *fd_list[MAXFILES];
211f08c3bdfSopenharmony_ci	int i;
212f08c3bdfSopenharmony_ci
213f08c3bdfSopenharmony_ci	/* Open files */
214f08c3bdfSopenharmony_ci	for (i = 0; i < numfiles; i++) {
215f08c3bdfSopenharmony_ci		if (debug)
216f08c3bdfSopenharmony_ci			printf("Thread  %d : Opening file number %d \n",
217f08c3bdfSopenharmony_ci			       thread_id, i);
218f08c3bdfSopenharmony_ci		if ((fd_list[i] = fopen(filename, "rw")) == NULL) {
219f08c3bdfSopenharmony_ci			sprintf(errmsg, "FAIL - Couldn't open file #%d", i);
220f08c3bdfSopenharmony_ci			perror(errmsg);
221f08c3bdfSopenharmony_ci			if (i > 0) {
222f08c3bdfSopenharmony_ci				close_files(fd_list, i - 1);
223f08c3bdfSopenharmony_ci			}
224f08c3bdfSopenharmony_ci			unlink(filename);
225f08c3bdfSopenharmony_ci			pthread_exit((void *)1);
226f08c3bdfSopenharmony_ci		}
227f08c3bdfSopenharmony_ci	}
228f08c3bdfSopenharmony_ci
229f08c3bdfSopenharmony_ci	/* Grab mutex lock */
230f08c3bdfSopenharmony_ci	if (pthread_mutex_lock(&c.m)) {
231f08c3bdfSopenharmony_ci		perror("FAIL - failed to grab mutex lock");
232f08c3bdfSopenharmony_ci		close_files(fd_list, numfiles);
233f08c3bdfSopenharmony_ci		unlink(filename);
234f08c3bdfSopenharmony_ci		pthread_exit((void *)1);
235f08c3bdfSopenharmony_ci	}
236f08c3bdfSopenharmony_ci
237f08c3bdfSopenharmony_ci	/* Check if you should wake up main thread */
238f08c3bdfSopenharmony_ci	if (++c.thr_sleeping == numthreads)
239f08c3bdfSopenharmony_ci		if (pthread_cond_signal(&c.init_cv)) {
240f08c3bdfSopenharmony_ci			perror("FAIL - failed to signal main thread");
241f08c3bdfSopenharmony_ci			close_files(fd_list, numfiles);
242f08c3bdfSopenharmony_ci			unlink(filename);
243f08c3bdfSopenharmony_ci			pthread_exit((void *)1);
244f08c3bdfSopenharmony_ci		}
245f08c3bdfSopenharmony_ci
246f08c3bdfSopenharmony_ci	/* Sleep until woken up */
247f08c3bdfSopenharmony_ci	if (pthread_cond_wait(&c.thr_cv, &c.m)) {
248f08c3bdfSopenharmony_ci		perror("FAIL - failed to wake up correctly");
249f08c3bdfSopenharmony_ci		close_files(fd_list, numfiles);
250f08c3bdfSopenharmony_ci		unlink(filename);
251f08c3bdfSopenharmony_ci		pthread_exit((void *)1);
252f08c3bdfSopenharmony_ci	}
253f08c3bdfSopenharmony_ci
254f08c3bdfSopenharmony_ci	/* Release mutex lock */
255f08c3bdfSopenharmony_ci	if (pthread_mutex_unlock(&c.m)) {
256f08c3bdfSopenharmony_ci		perror("FAIL - failed to release mutex lock");
257f08c3bdfSopenharmony_ci		close_files(fd_list, numfiles);
258f08c3bdfSopenharmony_ci		unlink(filename);
259f08c3bdfSopenharmony_ci		pthread_exit((void *)1);
260f08c3bdfSopenharmony_ci	}
261f08c3bdfSopenharmony_ci
262f08c3bdfSopenharmony_ci	/* Close file handles and exit */
263f08c3bdfSopenharmony_ci	close_files(fd_list, numfiles);
264f08c3bdfSopenharmony_ci	unlink(filename);
265f08c3bdfSopenharmony_ci	pthread_exit(NULL);
266f08c3bdfSopenharmony_ci}
267