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 68extern int gL1CacheEnabled; 69 70/* 71 * Your state variables should live in the tsd_t struct below 72 */ 73typedef struct { 74} tsd_t; 75 76#define HOSTNAME_LEN 125 77static int host_min=-1, host_range=0; 78static char *hostname_format=NULL; 79static char *hostname_list=NULL; 80 81int 82benchmark_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 100int 101parse_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 */ 132int 133benchmark_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// 163int 164benchmark_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 194int 195benchmark(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() 226int 227benchmark_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 237char * 238benchmark_result() 239{ 240 static char result = '\0'; 241 debug("benchmark_result"); 242 return (&result); 243} 244 245