• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *   Copyright (c) International Business Machines Corp., 2001-2004
3  *
4  *   This program is free software;  you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  *   the GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program;  if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/resource.h>
21 #include <sys/wait.h>
22 #include <sys/time.h>
23 #include <sys/select.h>
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #include <string.h>
29 #include <limits.h>
30 #include <errno.h>
31 #include <pthread.h>
32 
33 #include "config.h"
34 #include "fh.h"
35 #include "util.h"
36 
ffsb_get_filesize(char * name)37 uint64_t ffsb_get_filesize(char *name)
38 {
39 #ifndef HAVE_STAT64
40 #define STAT(a, b) do { stat((a), (b)); } while (0)
41 	struct stat filestat;
42 #else
43 #define STAT(a, b) do { stat64((a), (b)); } while (0)
44 	struct stat64 filestat;
45 #endif
46 
47 	STAT(name, &filestat);
48 	return (uint64_t) filestat.st_size;
49 #undef STAT
50 }
51 
ffsb_malloc(size_t size)52 void *ffsb_malloc(size_t size)
53 {
54 	void *ptr = malloc((size));
55 	assert(ptr != NULL);
56 	memset(ptr, 0, size);
57 	return ptr;
58 }
59 
ffsb_realloc(void * ptr,size_t size)60 void *ffsb_realloc(void *ptr, size_t size)
61 {
62 	void *tmp;
63 	/* printf("ffsb_realloc: ptr = %p  size = %ld\n",ptr,size); */
64 
65 	if (ptr == NULL)
66 		return ffsb_malloc(size);
67 
68 	tmp = realloc(ptr, size);
69 	assert(ptr != NULL);
70 	ptr = tmp;
71 	return ptr;
72 }
73 
ffsb_align_4k(void * ptr)74 void *ffsb_align_4k(void *ptr)
75 {
76 	unsigned long mask = ~(0xfff);	/* 12 zeros at the end */
77 	void *ret = (void *)((unsigned long)ptr & mask);
78 	/* printf("align_4k got %p returning %p\n",ptr,ret); */
79 	return ret;
80 }
81 
ffsb_strdup(const char * str)82 char *ffsb_strdup(const char *str)
83 {
84 	int len = strlen(str);
85 	char *dup = ffsb_malloc(len + 1);
86 	/* !!! am I off by one here ?? */
87 	strncpy(dup, str, len + 1);
88 	return dup;
89 }
90 
ffsb_strnlen(const char * str,size_t maxlen)91 size_t ffsb_strnlen(const char *str, size_t maxlen)
92 {
93 	size_t index = 0;
94 
95 	while (index < maxlen) {
96 		if (str[index] == '\0')
97 			break;
98 		index++;
99 	}
100 	return index;
101 }
102 
103 /* not perfect, in case we are somehow interrupted it's borked */
ffsb_sleep(unsigned secs)104 void ffsb_sleep(unsigned secs)
105 {
106 	struct timeval tv = { 0, 0 };
107 	tv.tv_sec = secs;
108 	select(0, NULL, NULL, NULL, &tv);
109 }
110 
ffsb_printsize(char * buf,double size,int bufsize)111 char *ffsb_printsize(char *buf, double size, int bufsize)
112 {
113 	if (size >= 1024 * 1024 * 1024)
114 		snprintf(buf, bufsize, "%.3gGB", size / (1024 * 1024 * 1024));
115 	else if (size >= 1024 * 1024)
116 		snprintf(buf, bufsize, "%.3gMB", size / (1024 * 1024));
117 	else if (size >= 1024)
118 		snprintf(buf, bufsize, "%.3gKB", size / 1024);
119 	else
120 		snprintf(buf, bufsize, "%.3gB", size);
121 
122 	return buf;
123 }
124 
ffsb_mkdir(char * dirname)125 void ffsb_mkdir(char *dirname)
126 {
127 	if (mkdir(dirname, S_IRWXU) < 0) {
128 		fprintf(stderr, "Error creating %s\n", dirname);
129 		perror("mkdir");
130 		exit(1);
131 	}
132 }
133 
tvsub(struct timeval t1,struct timeval t0)134 struct timeval tvsub(struct timeval t1, struct timeval t0)
135 {
136 	struct timeval tdiff;
137 	tdiff.tv_sec = t1.tv_sec - t0.tv_sec;
138 	tdiff.tv_usec = t1.tv_usec - t0.tv_usec;
139 	if (tdiff.tv_usec < 0)
140 		tdiff.tv_sec--, tdiff.tv_usec += 1000000;
141 	return tdiff;
142 }
143 
tvadd(struct timeval t1,struct timeval t0)144 struct timeval tvadd(struct timeval t1, struct timeval t0)
145 {
146 	struct timeval tdiff;
147 	tdiff.tv_sec = t1.tv_sec + t0.tv_sec;
148 	tdiff.tv_usec = t1.tv_usec + t0.tv_usec;
149 	if (tdiff.tv_usec > 1000000)
150 		tdiff.tv_sec++, tdiff.tv_usec -= 1000000;
151 	return tdiff;
152 }
153 
tvtodouble(struct timeval * t)154 double tvtodouble(struct timeval *t)
155 {
156 	return ((double)t->tv_sec * (1000000.0f) + (double)t->tv_usec) /
157 	    1000000.0f;
158 }
159 
cpu_so_far(void)160 double cpu_so_far(void)
161 {
162 	struct rusage rusage;
163 
164 	getrusage(RUSAGE_SELF, &rusage);
165 
166 	return
167 	    ((double)rusage.ru_utime.tv_sec) +
168 	    (((double)rusage.ru_utime.tv_usec) / 1000000.0) +
169 	    ((double)rusage.ru_stime.tv_sec) +
170 	    (((double)rusage.ru_stime.tv_usec) / 1000000.0);
171 }
172 
cpu_so_far_children(void)173 double cpu_so_far_children(void)
174 {
175 	struct rusage rusage;
176 
177 	getrusage(RUSAGE_CHILDREN, &rusage);
178 
179 	return
180 	    ((double)rusage.ru_utime.tv_sec) +
181 	    (((double)rusage.ru_utime.tv_usec) / 1000000.0) +
182 	    ((double)rusage.ru_stime.tv_sec) +
183 	    (((double)rusage.ru_stime.tv_usec) / 1000000.0);
184 }
185 
186 /* !!!! check portability */
getfsutil(char * dirname)187 float getfsutil(char *dirname)
188 {
189 	struct statvfs64 fsdata;
190 
191 	statvfs64(dirname, &fsdata);
192 
193 /* 	return (float)(fsdata.f_blocks-fsdata.f_bfree)/ */
194 /* 		(float)(fsdata.f_blocks-fsdata.f_bfree+fsdata.f_bavail); */
195 	return (float)(((float)(fsdata.f_blocks - fsdata.f_bfree)) /
196 		       ((float)fsdata.f_blocks));
197 }
198 
getfsutil_size(char * dirname)199 uint64_t getfsutil_size(char *dirname)
200 {
201 	struct statvfs64 fsdata;
202 	statvfs64(dirname, &fsdata);
203 
204 	return (fsdata.f_blocks - fsdata.f_bfree) * fsdata.f_bsize;
205 }
206 
ffsb_system(char * command)207 int ffsb_system(char *command)
208 {
209 	int pid = 0, status;
210 	extern char **environ;
211 
212 	if (command == NULL)
213 		return 1;
214 	pid = fork();
215 	if (pid == -1)
216 		return -1;
217 	if (pid == 0) {
218 		char *argv[4];
219 		argv[0] = "sh";
220 		argv[1] = "-c";
221 		argv[2] = command;
222 		argv[3] = 0;
223 		execve("/bin/sh", argv, environ);
224 		exit(127);
225 	}
226 	do {
227 		if (waitpid(pid, &status, 0) == -1) {
228 			if (errno != EINTR)
229 				return -1;
230 		} else
231 			return status;
232 	} while (1);
233 }
234 
ffsb_sync()235 void ffsb_sync()
236 {
237 	struct timeval starttime, endtime, difftime;
238 	printf("Syncing()...");
239 	fflush(stdout);
240 	gettimeofday(&starttime, NULL);
241 	sync();
242 	gettimeofday(&endtime, NULL);
243 	timersub(&endtime, &starttime, &difftime);
244 	printf("%ld sec\n", difftime.tv_sec);
245 }
246 
ffsb_getrusage(struct rusage * ru_self,struct rusage * ru_children)247 void ffsb_getrusage(struct rusage *ru_self, struct rusage *ru_children)
248 {
249 	int ret = 0;
250 /* 	printf("cpu_so_far is %lf\n",cpu_so_far()); */
251 /* 	printf("cpu_so_far_children is %lf\n",cpu_so_far_children()); */
252 	ret = getrusage(RUSAGE_SELF, ru_self);
253 	if (ret < 0)
254 		perror("getrusage self");
255 
256 /* 	printf("self returned %d\n",ret); */
257 	ret = getrusage(RUSAGE_CHILDREN, ru_children);
258 	if (ret < 0)
259 		perror("getrusage children");
260 /* 	printf("children returned %d\n",ret); */
261 }
262 
ffsb_milli_sleep(unsigned time)263 void ffsb_milli_sleep(unsigned time)
264 {
265 	struct timeval tv = { 0, 0 };
266 	if (!time)
267 		return;
268 	tv.tv_usec = time * 1000;
269 	select(0, NULL, NULL, NULL, &tv);
270 }
271 
ffsb_micro_sleep(unsigned time)272 void ffsb_micro_sleep(unsigned time)
273 {
274 	struct timeval tv = { 0, 0 };
275 	if (!time)
276 		return;
277 	tv.tv_usec = time;
278 	select(0, NULL, NULL, NULL, &tv);
279 }
280 
ffsb_barrier_init(ffsb_barrier_t * fb,unsigned count)281 void ffsb_barrier_init(ffsb_barrier_t * fb, unsigned count)
282 {
283 	memset(fb, 0, sizeof(*fb));
284 	pthread_mutex_init(&fb->plock, NULL);
285 	pthread_cond_init(&fb->pcond, NULL);
286 	fb->required_count = count;
287 }
288 
ffsb_barrier_wait(ffsb_barrier_t * fb)289 void ffsb_barrier_wait(ffsb_barrier_t * fb)
290 {
291 	pthread_mutex_lock(&fb->plock);
292 
293 	fb->current_count++;
294 
295 	if (fb->current_count == fb->required_count)
296 		pthread_cond_broadcast(&fb->pcond);
297 	else
298 		while (fb->current_count != fb->required_count)
299 			pthread_cond_wait(&fb->pcond, &fb->plock);
300 
301 	pthread_mutex_unlock(&fb->plock);
302 }
303 
ffsb_unbuffer_stdout(void)304 void ffsb_unbuffer_stdout(void)
305 {
306 #ifndef SETVBUF_REVERSED
307 	setvbuf(stdout, NULL, _IONBF, 0);
308 #else
309 	setvbuf(stdout, _IONBF, NULL, 0);
310 #endif
311 }
312 
ffsb_bench_gettimeofday(void)313 void ffsb_bench_gettimeofday(void)
314 {
315 	unsigned long i = 0;
316 	uint64_t total_usec;
317 	uint64_t average = 0;
318 	struct timeval starttime, endtime, junk, difftime;
319 	gettimeofday(&starttime, NULL);
320 	for (i = 0; i < 1000000; i++)
321 		gettimeofday(&junk, NULL);
322 	gettimeofday(&endtime, NULL);
323 	timersub(&endtime, &starttime, &difftime);
324 	total_usec = difftime.tv_sec * 1000000;
325 	total_usec += difftime.tv_usec;
326 	average = total_usec / 1000ull;
327 	printf("average time for gettimeofday(): %llu nsec\n", average);
328 }
329 
ffsb_bench_getpid(void)330 void ffsb_bench_getpid(void)
331 {
332 	unsigned long i = 0;
333 	uint64_t total_usec;
334 	uint64_t average = 0;
335 	struct timeval starttime, endtime, difftime;
336 	gettimeofday(&starttime, NULL);
337 	for (i = 0; i < 1000000; i++)
338 		getpid();
339 	gettimeofday(&endtime, NULL);
340 	timersub(&endtime, &starttime, &difftime);
341 	total_usec = difftime.tv_sec * 1000000;
342 	total_usec += difftime.tv_usec;
343 	average = total_usec / 1000ull;
344 	printf("average time for getpid(): %llu nsec\n", average);
345 }
346