]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/libMicro/apple/getgrnam.c
xnu-4570.41.2.tar.gz
[apple/xnu.git] / tools / tests / libMicro / apple / getgrnam.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
36 // add additional headers needed here.
37
38 #include "../libmicro.h"
39 #include <grp.h>
40 #include <uuid/uuid.h>
41
42 #if DEBUG
43 # define debug(fmt, args...) (void) fprintf(stderr, fmt "\n" , ##args)
44 #else
45 # define debug(fmt, args...)
46 #endif
47
48
49 // Correct use case
50 //
51 // getgrnam -E -L -S -W -B 200 -C 10 -r 10
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 // -r is the number of total groups (from "local_test_group1" to "local_test_group#")
62
63 extern int gL1CacheEnabled;
64
65 /*
66 * Your state variables should live in the tsd_t struct below
67 */
68 typedef struct {
69 } tsd_t;
70
71 // temporary buffer size
72 #define BUFSIZE 200
73
74 // the number of record lookup to issue is covered by standard option optB
75 static int optRecords = 10; // the number of total records
76
77 // This will use local users (local_test_*)
78 static char *default_gprefix = "ds_test_group";
79
80 #define GROUPNAME_LEN 30
81 static char *grpname_list;
82
83 int
84 benchmark_init()
85 {
86 debug("benchmark_init");
87 (void) sprintf(lm_optstr, "l:r:g:");
88
89 lm_tsdsize = sizeof (tsd_t);
90 lm_defB = 100;
91
92 (void) sprintf(lm_usage,
93 "\n ------- getgrnam specific options (default: *)\n"
94 " [-r total number of group records (10*)]\n"
95 " [-g group prefix(ds_test_group)]\n"
96 "\n" );
97 return (0);
98 }
99
100 /*
101 * This is where you parse your lower-case arguments.
102 */
103 int
104 benchmark_optswitch(int opt, char *optarg)
105 {
106 debug("benchmark_optswitch");
107
108 switch (opt) {
109 case 'r': // total number of records. default is 100
110 optRecords = atoi(optarg);
111 debug("optRecords = %d\n", optRecords);
112 break;
113
114 case 'l':
115 gL1CacheEnabled = atoi(optarg);
116 break;
117
118 case 'g': // base name for the groups to use
119 default_gprefix = strdup(optarg);
120 debug("default_gprefix = %s\n", default_gprefix);
121 break;
122
123 default:
124 return -1;
125 }
126
127 return 0;
128 }
129
130
131 // Initialize all structures that will be used in benchmark()
132 // moved template init from benchmark_initworker -> benchmark_initrun
133 // since username_list is static across threads and processes
134 //
135 int
136 benchmark_initrun()
137 {
138 int i;
139
140 debug("\nbenchmark_initrun");
141
142 // create an array of usernames to use in benchmark before their use
143 // realtime generation in benchmark effects performance measurements
144 grpname_list = malloc( optRecords * GROUPNAME_LEN );
145 if (!grpname_list) {
146 debug ("malloc error");
147 exit (1);
148 }
149
150 for (i = 0; i < optRecords; i++) {
151 sprintf(&grpname_list[i*GROUPNAME_LEN], "%s%d", default_gprefix, i+1);
152 debug("creating group name %s", &grpname_list[i*GROUPNAME_LEN]);
153 }
154
155 return (0);
156 }
157
158
159 int
160 benchmark(void *tsd, result_t *res)
161 {
162 int i, err;
163 struct group *grp = NULL;
164
165 res->re_errors = 0;
166
167 debug("in to benchmark - optB = %i", lm_optB);
168 srandom(getpid());
169
170 for (i = 0; i < lm_optB; i++) {
171 int index = (random() % optRecords) * GROUPNAME_LEN;
172
173 if (lm_optT > 1) {
174 struct group gd;
175 struct group *grp_ptr = &gd;
176 struct group *tmp_ptr;
177 char gbuf[BUFSIZE];
178
179 err = getgrnam_r( &grpname_list[index], grp_ptr, gbuf, BUFSIZE, &tmp_ptr);
180 // non-NULL err means failure and NULL result ptr means no matching
181 // entry
182 if (err) {
183 debug("error: %s -> %s", &grpname_list[index], strerror(err));
184 res->re_errors++;
185 }
186 else if ( !tmp_ptr) {
187 debug("not found: %s", &grpname_list[index] );
188 res->re_errors++;
189 }
190 }
191 else {
192 errno = 0;
193 grp = getgrnam( &grpname_list[index] );
194
195 if (!grp) {
196 if (errno) {
197 debug("error: %s -> %s", &grpname_list[index], strerror(errno));
198 res->re_errors++;
199 }
200 else {
201 debug("not found: %s", &grpname_list[index] );
202 res->re_errors++;
203 }
204 }
205 }
206 }
207 res->re_count = i;
208
209 return (0);
210 }
211
212 // We need to release all the structures we allocated in benchmark_initrun()
213 int
214 benchmark_finirun(void *tsd)
215 {
216 // tsd_t *ts = (tsd_t *)tsd;
217 debug("benchmark_finiworker: deallocating structures");
218
219 free (grpname_list);
220
221 return (0);
222 }
223
224 char *
225 benchmark_result()
226 {
227 static char result = '\0';
228 debug("benchmark_result");
229 return (&result);
230 }
231