]> git.saurik.com Git - apple/xnu.git/blob - tools/tests/libMicro/apple/getgrgid.c
f49925d18bc98c880d37d3c4759b34078c91ffa7
[apple/xnu.git] / tools / tests / libMicro / apple / getgrgid.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 <membership.h>
40 #include <grp.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 // getgrgid -E -L -S -W -B 200 -C 10 -g 1211-1213
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 // -g gid range in the form of "min-max". For example, -g 1211-1213
62 //
63
64 extern int gL1CacheEnabled;
65
66 /*
67 * Your state variables should live in the tsd_t struct below
68 */
69 typedef struct {
70 } tsd_t;
71
72 // temporary buffer size
73 #define BUFSIZE 200
74 #define INVALID_ID -1
75
76 static gid_t gid_min = INVALID_ID;
77 static int gid_range = 0; // gid_max = gid_min + gid_range
78
79 int
80 benchmark_init()
81 {
82 debug("benchmark_init");
83 (void) sprintf(lm_optstr, "l:g:");
84
85 lm_tsdsize = sizeof (tsd_t);
86 lm_defB = 100;
87
88 (void) sprintf(lm_usage,
89 "\n ------- getgrgid specific options (default: *)\n"
90 " [-g GID range (min-max)]\n"
91 "\n" );
92 return (0);
93 }
94
95
96 int
97 parse_range(gid_t *min, int *offset, char *buf)
98 {
99 char *value, *tmp_ptr = strdup(buf);
100 int range=0;
101 debug("parse_range");
102
103 value = strsep(&tmp_ptr, "-");
104 *min = atoi(value);
105 debug("min = %d", *min);
106 if (tmp_ptr) {
107 value = strsep(&tmp_ptr, "-");
108 range = atoi(value);
109 if (range < *min) {
110 printf("max id should be larger than min id\n");
111 return -1;
112 }
113 *offset = range - *min + 1;
114 debug("range = %d", *offset);
115 }
116 else {
117 printf("argument should be in the form of min-max\n");
118 return -1;
119 }
120
121 return 0;
122
123 }
124
125 /*
126 * This is where you parse your lower-case arguments.
127 */
128 int
129 benchmark_optswitch(int opt, char *optarg)
130 {
131 debug("benchmark_optswitch");
132
133 switch (opt) {
134 case 'l':
135 gL1CacheEnabled = atoi(optarg);
136 break;
137
138 case 'g': // GID range
139 return parse_range( &gid_min, &gid_range, optarg);
140 break;
141
142 default:
143 return -1;
144 }
145
146 return 0;
147 }
148
149
150 // Initialize all structures that will be used in benchmark()
151 // moved template init from benchmark_initworker -> benchmark_initrun
152 //
153 int
154 benchmark_initrun()
155 {
156 debug("\nbenchmark_initrun");
157
158 return (0);
159 }
160
161
162 int
163 benchmark(void *tsd, result_t *res)
164 {
165 int i, err;
166 struct group *grp = NULL;
167
168 res->re_errors = 0;
169
170 debug("in to benchmark - optB = %i", lm_optB);
171 for (i = 0; i < lm_optB; i++) {
172 gid_t gid = gid_min + random() % gid_range ;
173
174 if (lm_optT > 1) {
175 struct group gd;
176 struct group *grp_ptr = &gd;
177 struct group *tmp_ptr;
178 char gbuf[BUFSIZE];
179
180 err = getgrgid_r( gid, grp_ptr, gbuf, BUFSIZE, &tmp_ptr);
181 if (err) {
182 debug("error: GID %d -> %s", gid, strerror(err));
183 res->re_errors++;
184 }
185 else if (!tmp_ptr) {
186 debug("not found: GID %d", gid);
187 res->re_errors++;
188 }
189 }
190 else {
191 errno = 0;
192 grp = getgrgid( gid );
193
194 if (!grp) {
195 if (errno) {
196 debug("error: GID %d -> %s", gid, strerror(errno));
197 res->re_errors++;
198 }
199 else {
200 debug("not found: GID %d", gid);
201 res->re_errors++;
202 }
203 }
204 }
205 }
206 res->re_count = i;
207
208 return (0);
209 }
210
211 // We need to release all the structures we allocated in benchmark_initrun()
212 int
213 benchmark_finirun(void *tsd)
214 {
215 // tsd_t *ts = (tsd_t *)tsd;
216 debug("benchmark_finirun ");
217
218 return (0);
219 }
220
221 char *
222 benchmark_result()
223 {
224 static char result = '\0';
225 debug("benchmark_result");
226 return (&result);
227 }
228