]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/libMicro/apple/getaddrinfo_host.c
a7041753fbd1b1c14fc2f16b974b000615656ee8
[apple/xnu.git] / tools / tests / libMicro / apple / getaddrinfo_host.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 #include <unistd.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <stdbool.h>
33 #include <errno.h>
34 #include <string.h>
35 #include <netdb.h>
36
37 // add additional headers needed here.
38
39 #include "../libmicro.h"
40
41 #if DEBUG
42 # define debug(fmt, args...) (void) fprintf(stderr, fmt "\n" , ##args)
43 #else
44 # define debug(fmt, args...)
45 #endif
46
47
48 //
49 // Correct use case
50 //
51 // getaddrinfo_host -E -L -S -W -B 200 -C 100 -s "server%d"
52 //
53 // libMicro default benchmark run options are "-E -L -S -W -C 200"
54 //
55 // -B is batch size: loop iteration per each benchmark run. Needs to match # of
56 // real lookups. This is total number of lookups to issue.
57 // -C is min sample number: how many benchmark needs to run to get proper sample
58 // 1 is mimumum, but you get at least 3 benchmark run
59 // samples. Do not set to zero. Default is 200 for most
60 // runs in libMicro.
61 // -h is hostname format: for example, "server-%d.performance.rack"
62 // this is C language string format that can include %d
63 // -r hostname digit range in the form of "min-max". For example, -r 100-112
64 // With -h and -r, resulting hostnames are
65 // server-100.performance.rack - server-112.performance.rack
66 //
67
68 extern int gL1CacheEnabled;
69
70 /*
71 * Your state variables should live in the tsd_t struct below
72 */
73 typedef struct {
74 } tsd_t;
75
76 #define HOSTNAME_LEN 125
77 static int host_min=-1, host_range=0;
78 static char *hostname_format=NULL;
79 static char *hostname_list=NULL;
80
81 int
82 benchmark_init()
83 {
84 debug("benchmark_init");
85 (void) sprintf(lm_optstr, "l:h:r:");
86
87 lm_tsdsize = sizeof (tsd_t);
88 lm_defB = 100;
89
90 (void) sprintf(lm_usage,
91 "\n ------- getaddrinfo_host specific options (default: *)\n"
92 " [-h \"hostname format\"]. ie. \"server-%%d.perf\"\n"
93 " [-r min-max]\n"
94 "\n" );
95
96 return (0);
97 }
98
99
100 int
101 parse_range(int *min, int *offset, char *buf)
102 {
103 char *value, *tmp_ptr = strdup(buf);
104 int range=0;
105 debug("parse_range");
106
107 value = strsep(&tmp_ptr, "-");
108 *min = atoi(value);
109 debug("min = %d", *min);
110 if (tmp_ptr) {
111 value = strsep(&tmp_ptr, "-");
112 range = atoi(value);
113 if (range < *min) {
114 printf("max id should be larger than min id\n");
115 return -1;
116 }
117 *offset = range - *min + 1; // 1-based
118 debug("range = %d", *offset);
119 }
120 else {
121 printf("argument should be in the form of min-max\n");
122 return -1;
123 }
124
125 return 0;
126
127 }
128
129 /*
130 * This is where you parse your lower-case arguments.
131 */
132 int
133 benchmark_optswitch(int opt, char *optarg)
134 {
135 debug("benchmark_optswitch");
136
137 switch (opt) {
138 case 'h': // hostname string format
139 hostname_format = strdup(optarg);
140 debug ("hostname format: %s", hostname_format);
141 break;
142
143 case 'l':
144 gL1CacheEnabled = atoi(optarg);
145 break;
146
147 case 'r': // UID range
148 return parse_range( &host_min, &host_range, optarg);
149 break;
150
151 default:
152 return -1;
153 }
154
155
156
157 return 0;
158 }
159
160
161 // Initialize all structures that will be used in benchmark()
162 //
163 int
164 benchmark_initrun()
165 {
166 int i;
167
168 debug("\nbenchmark_initrun");
169
170 if (host_min == -1) {
171 printf("-r min-max needs to be specified\n");
172 exit (1);
173 }
174
175 if (!hostname_format) {
176 printf("-h hostname_format needs to be specified\n");
177 exit (1);
178 }
179
180 hostname_list = malloc ( host_range * HOSTNAME_LEN );
181 if (!hostname_list) {
182 debug("malloc error");
183 exit (1);
184 }
185
186 for (i = 0; i < host_range; i++) {
187 sprintf( &hostname_list[i*HOSTNAME_LEN], hostname_format, i+host_min);
188 // debug("hostname: %s", &hostname_list[i*HOSTNAME_LEN]);
189 }
190 return (0);
191 }
192
193
194 int
195 benchmark(void *tsd, result_t *res)
196 {
197 int i, index, err;
198 struct addrinfo *addi;
199
200 res->re_errors = 0;
201
202 debug("in to benchmark - optB = %i", lm_optB);
203 srandom(getpid());
204
205 for (i = 0; i < lm_optB; i++) {
206 index = HOSTNAME_LEN * (random() % host_range);
207
208 err = getaddrinfo( &hostname_list[index], NULL, NULL, &addi);
209
210 if (err) {
211 debug("%s: error: %s", &hostname_list[index], gai_strerror(err));
212 res->re_errors++;
213 }
214 else {
215 debug("host %s done", &hostname_list[index]);
216 }
217
218 freeaddrinfo (addi);
219 }
220 res->re_count = i;
221
222 return (0);
223 }
224
225 // We need to release all the structures we allocated in benchmark_initrun()
226 int
227 benchmark_finirun(void *tsd)
228 {
229 // tsd_t *ts = (tsd_t *)tsd;
230 debug("benchmark_finirun ");
231
232 free(hostname_list);
233
234 return (0);
235 }
236
237 char *
238 benchmark_result()
239 {
240 static char result = '\0';
241 debug("benchmark_result");
242 return (&result);
243 }
244