]> git.saurik.com Git - apple/xnu.git/blame - tools/tests/libMicro/apple/lmbench_select_file.c
xnu-3789.1.32.tar.gz
[apple/xnu.git] / tools / tests / libMicro / apple / lmbench_select_file.c
CommitLineData
b0d623f7
A
1/*
2 * Copyright (c) 2006 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29
30/*
31 * Order of Execution
32 *
33 * benchmark_init
34 *
35 * benchmark_optswitch
36 *
37 * benchmark_initrun
38 *
39 * benchmark_initworker
40 * benchmark_initbatch
41 * benchmark
42 * benchmark_finibatch
43 * benchmark_initbatch
44 * benchmark
45 * benchmark_finibatch, etc.
46 * benchmark_finiworker
47 *
48 * benchmark_result
49 *
50 * benchmark_finirun
51 *
52 * benchmark_fini
53 */
54
55
56
57#ifdef __sun
58#pragma ident "@(#)socket.c 1.3 05/08/04 Apple Inc."
59#endif
60
61
62
63#include <unistd.h>
64#include <stdlib.h>
65#include <stdio.h>
66#include <fcntl.h>
67#include <string.h>
68#include <errno.h>
69
70#include "../libmicro.h"
71
72/*
73 * lmbench routines, etc. brought over for this benchmark
74 */
75int open_file(void* tsd);
76void server(void* tsd);
77
78
79typedef int (*open_f)(void* tsd);
80/*
81 * end of lmbench support routines
82 */
83
84/*
85 * Your state variables should live in the tsd_t struct below
86 */
87typedef struct {
88 char fname[L_tmpnam];
89 open_f fid_f;
90 pid_t pid;
91 int sock;
92 int fid;
93 int num;
94 int max;
95 fd_set set;
96} tsd_t;
97
98static int optt = 1;
99static int optn = -1;
100static int optp = 1;
101static int optw = 0;
102
103/*
104 * lmbench routines, etc. brought over for this benchmark
105 */
106
107void
108morefds(void)
109{
110#ifdef RLIMIT_NOFILE
111 struct rlimit r;
112
113 getrlimit(RLIMIT_NOFILE, &r);
114 r.rlim_cur = r.rlim_max;
115 setrlimit(RLIMIT_NOFILE, &r);
116#endif
117}
118
119int
120open_file(void* tsd)
121{
122 tsd_t* ts = (tsd_t*)tsd;
123 //(void) fprintf(stderr, "open_file: ts->fname = %s\n",ts->fname);
124 return (int) open(ts->fname, O_RDONLY);
125}
126
127void
128server(void* tsd)
129{
130 int pid;
131 tsd_t* ts = (tsd_t*)tsd;
132
133 pid = getpid();
134 ts->pid = 0;
135 //(void) fprintf(stderr, "server: state->fid_f = %i\n",ts->fid_f);
136
137 if (ts->fid_f == open_file) {
138 /* Create a temporary file for clients to open */
139 sprintf(ts->fname, "/tmp/lat_selectXXXXXX");
140 //(void) fprintf(stderr, "server: ts->fname = %s\n",ts->fname);
141 ts->fid = mkstemp(ts->fname);
142 //(void) fprintf(stderr, "server: ts->fname = %s: ts->fid = %d\n",ts->fname, ts->fid);
143
144 if (ts->fid <= 0) {
145 char buf[L_tmpnam+128];
146 sprintf(buf, "lat_select: Could not create temp file %s", ts->fname);
147 perror(buf);
148 exit(1);
149 }
150 close(ts->fid);
151 return;
152 }
153//
154// this is all for the tcp version of this test only
155//
156// /* Create a socket for clients to connect to */
157// state->sock = tcp_server(TCP_SELECT, SOCKOPT_REUSE);
158// if (state->sock <= 0) {
159// perror("lat_select: Could not open tcp server socket");
160// exit(1);
161// }
162
163 /* Start a server process to accept client connections */
164// switch(state->pid = fork()) {
165// case 0:
166// /* child server process */
167// while (pid == getppid()) {
168// int newsock = tcp_accept(state->sock, SOCKOPT_NONE);
169// read(newsock, &state->fid, 1);
170// close(newsock);
171// }
172// exit(0);
173// case -1:
174// /* error */
175// perror("lat_select::server(): fork() failed");
176// exit(1);
177// default:
178// break;
179// }
180}
181
182
183/*
184 * end of lmbench support routines
185 */
186
187/*ARGSUSED*/
188int
189benchmark_initbatch(void *tsd)
190{
191 /*
192 * initialize your state variables here second
193 */
194 return (0);
195}
196
197int
198benchmark_finirun()
199{
200 //(void) fprintf(stderr, "benchmark_finirun\n");
201 return (0);
202}
203
204int
205benchmark_init()
206{
207 //(void) fprintf(stderr, "benchmark_init\n");
208 /*
209 * the lm_optstr must be defined here or no options for you
210 *
211 * ...and the framework will throw an error
212 *
213 */
214 (void) sprintf(lm_optstr, "p:w:n:t:");
215 /*
216 * working hypothesis:
217 *
218 * tsd_t is the struct that we can pass around our
219 * state info in
220 *
221 * lm_tsdsize will allocate the space we need for this
222 * structure throughout the rest of the framework
223 */
224 lm_tsdsize = sizeof (tsd_t);
225
226 (void) sprintf(lm_usage,
227 " [-p parallelism (default 1)]\n"
228 " [-w warmup (default 0)]\n"
229 " [-n number of descriptors (default 1)]\n"
230 " [-t int (default 1)]\n"
231 "notes: measures lmbench_select_file\n");
232 lm_defB = 1;
233 return (0);
234}
235
236int
237benchmark_fini()
238{
239 //(void) fprintf(stderr, "benchmark_fini\n");
240 return (0);
241}
242
243int
244benchmark_finibatch(void *tsd)
245{
246 return (0);
247}
248
249char *
250benchmark_result()
251{
252 static char result = '\0';
253 //(void) fprintf(stderr, "benchmark_result\n");
254 return (&result);
255}
256
257int
258benchmark_finiworker(void *tsd)
259{
260 tsd_t *ts = (tsd_t *)tsd;
261 int i;
262 // pulls in the lmbench cleanup code
263 //(void) fprintf(stderr, "benchmark_finiworker\n");
264 for (i = 0; i <= ts->max; ++i) {
265 if (FD_ISSET(i, &(ts->set)))
266 close(i);
267 }
268 FD_ZERO(&(ts->set));
269 unlink(ts->fname);
270 return (0);
271}
272
273int
274benchmark_optswitch(int opt, char *optarg)
275{
276 //(void) fprintf(stderr, "benchmark_optswitch\n");
277
278 switch (opt) {
279 case 't':
280 optt = sizetoint(optarg);
281 break;
282 case 'n':
283 optn = sizetoint(optarg);
284 break;
285 case 'p':
286 optp = sizetoint(optarg);
287 break;
288 case 'w':
289 optw = sizetoint(optarg);
290 break;
291 default:
292 return (-1);
293 }
294 return (0);
295}
296
297int
298benchmark_initworker(void *tsd)
299{
300 // pulls in code from lmbench main and initialize
301 int n = 0;
302 /*
303 * initialize your state variables here first
304 */
305 tsd_t *ts = (tsd_t *)tsd;
306 int N, fid, fd;
307
308 /*
309 * default number of file descriptors
310 */
311 //(void) fprintf(stderr, "benchmark_initworker\n");
312 ts->num = 200;
313 if (optn > 0) {
314 ts->num = optn;
315 }
316 N = ts->num;
317 //(void) fprintf(stderr, "benchmark_initworker ts->num is %i\n",ts->num);
318
319 /*
320 * grab more file descriptors
321 */
322
323 morefds();
324
325 ts->fid_f = open_file;
326 server(ts);
327 //(void) fprintf(stderr, "benchmark_initworker: returned from server call\n");
328 /*
329 * Initialize function from lmbench
330 * for this test
331 */
332 fid = (*ts->fid_f)(ts);
333 //(void) fprintf(stderr, "initworker: fid is %i\n",fid);
334 if (fid <= 0) {
335 perror("Could not open device");
336 exit(1);
337 }
338 ts->max = 0;
339 FD_ZERO(&(ts->set));
340 //(void) fprintf(stderr, "initworker FD_ZERO: ts->set result is %i\n",ts->set);
341 //(void) fprintf(stderr, "initworker: N is %i\n",N);
342 for (n = 0; n < N; n++) {
343 //(void) fprintf(stderr, "benchmark_initworker: in the loop - N is %i: n is %i\n",N, n);
344 fd = dup(fid);
345 //(void) fprintf(stderr, "benchmark_initworker: dup result is %i\n",fd);
346 //(void) fprintf(stderr, "benchmark_initworker: errno result is %d - \"%s\"\n",errno, strerror(errno));
347
348 if (fd == -1) break;
349 if (fd > ts->max)
350 ts->max = fd;
351 FD_SET(fd, &(ts->set));
352 //(void) fprintf(stderr, "initworker FD_SET: ts->set result is %i\n",ts->set);
353
354 }
355 //(void) fprintf(stderr, "benchmark_initworker: after second macro/loop\n");
356
357 ts->max++;
358 close(fid);
359 //(void) fprintf(stderr, "benchmark_initworker: N is %i: n is %i\n",N, n);
360 if (n != N)
361 exit(1);
362 /* end of initialize function */
363 //(void) fprintf(stderr, "benchmark_initworker: about to exit\n");
364 return (0);
365}
366
367int
368benchmark_initrun()
369{
370 //(void) fprintf(stderr, "benchmark_initrun\n");
371 return (0);
372}
373
374int
375benchmark(void *tsd, result_t *res)
376{
377 /*
378 * initialize your state variables here last
379 *
380 * and realize that you are paying for your initialization here
381 * and it is really a bad idea
382 */
383 tsd_t *ts = (tsd_t *)tsd;
384 fd_set nosave;
385 static struct timeval tv;
386
387 //(void) fprintf(stderr, "benchmark\n");
388
389 int i;
390 //int sel_res;
391 tv.tv_sec = 0;
392 tv.tv_usec = 0;
393
394
395 for (i = 0; i < lm_optB; i++) {
396 nosave = ts->set;
397 //(void) fprintf(stderr, "benchmark: nosave is %i\n", nosave);
398
399 select(ts->num, 0, &nosave, 0, &tv);
400 //(void) fprintf(stderr, "benchmark: select result is %i\n",sel_res);
401 //(void) fprintf(stderr, "benchmark: errno result is %d - \"%s\"\n",errno, strerror(errno));
402
403
404 }
405 res->re_count = i;
406 return (0);
407}
408