]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/libMicro/apple/lmbench_select_file.c
xnu-1699.24.23.tar.gz
[apple/xnu.git] / tools / tests / libMicro / apple / lmbench_select_file.c
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 */
75 int open_file(void* tsd);
76 void server(void* tsd);
77
78
79 typedef 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 */
87 typedef 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
98 static int optt = 1;
99 static int optn = -1;
100 static int optp = 1;
101 static int optw = 0;
102
103 /*
104 * lmbench routines, etc. brought over for this benchmark
105 */
106
107 void
108 morefds(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
119 int
120 open_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
127 void
128 server(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*/
188 int
189 benchmark_initbatch(void *tsd)
190 {
191 /*
192 * initialize your state variables here second
193 */
194 return (0);
195 }
196
197 int
198 benchmark_finirun()
199 {
200 //(void) fprintf(stderr, "benchmark_finirun\n");
201 return (0);
202 }
203
204 int
205 benchmark_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
236 int
237 benchmark_fini()
238 {
239 //(void) fprintf(stderr, "benchmark_fini\n");
240 return (0);
241 }
242
243 int
244 benchmark_finibatch(void *tsd)
245 {
246 return (0);
247 }
248
249 char *
250 benchmark_result()
251 {
252 static char result = '\0';
253 //(void) fprintf(stderr, "benchmark_result\n");
254 return (&result);
255 }
256
257 int
258 benchmark_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
273 int
274 benchmark_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
297 int
298 benchmark_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
367 int
368 benchmark_initrun()
369 {
370 //(void) fprintf(stderr, "benchmark_initrun\n");
371 return (0);
372 }
373
374 int
375 benchmark(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