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 <pwd.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// Correct use case
49//
50//    getpwent -E  -L -S -W -B 200 -C 100
51//
52//      libMicro default benchmark run options are "-E -L -S -W -C 200"
53//
54// -B is batch size: loop iteration per each benchmark run. Needs to match # of
55//                   real lookups. This is total number of lookups to issue.
56// -C is min sample number: how many benchmark needs to run to get proper sample
57//                          1 is mimumum, but you get at least 3 benchmark run
58//                          samples. Do not set to zero. Default is 200 for most
59//                          runs in libMicro.
60//
61
62extern int gL1CacheEnabled;
63
64/*
65 *    Your state variables should live in the tsd_t struct below
66 */
67typedef struct {
68} tsd_t;
69
70
71int
72benchmark_init()
73{
74    debug("benchmark_init");
75
76    (void) sprintf(lm_optstr, "l:");
77    lm_tsdsize = sizeof (tsd_t);
78    lm_defB = 100;
79
80    return (0);
81}
82
83
84/*
85 * This is where you parse your lower-case arguments.
86 */
87int
88benchmark_optswitch(int opt, char *optarg)
89{
90    debug("benchmark_optswitch");
91
92    switch (opt) {
93        case 'l':
94            gL1CacheEnabled = atoi(optarg);
95            break;
96    }
97
98    return 0;
99}
100
101
102// Initialize all structures that will be used in benchmark()
103//
104int
105benchmark_initrun()
106{
107    debug("\nbenchmark_initrun");
108
109    return (0);
110}
111
112
113int
114benchmark(void *tsd, result_t *res)
115{
116    int         i;
117    struct passwd *passwd;
118
119    res->re_errors = 0;
120
121    debug("in to benchmark - optB = %i", lm_optB);
122    for (i = 0; i < lm_optB; i++) {
123
124        errno = 0;      // this is needed explicitly due to getpwent() design
125        passwd = getpwent();
126
127        if (!passwd) {
128            if (errno) {
129                debug("error: %s", strerror(errno));
130                res->re_errors++;
131            }
132            else {
133                // will not counted toward libmicro error
134                setpassent(1);  // rewind to the beginning of passwd file
135            }
136        }
137        else {
138            debug("pw_name: %s", passwd->pw_name);
139        }
140    }
141    res->re_count = i;
142
143    return (0);
144}
145
146// We need to release all the structures we allocated in benchmark_initrun()
147int
148benchmark_finirun(void *tsd)
149{
150    // tsd_t    *ts = (tsd_t *)tsd;
151    debug("benchmark_finirun ");
152
153    return (0);
154}
155
156char *
157benchmark_result()
158{
159    static char    result = '\0';
160    debug("benchmark_result");
161    return (&result);
162}
163
164