Merge from vendor branch GDB:
[dragonfly.git] / contrib / sendmail-8.13.4 / libsm / b-strl.c
1 /*
2  * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers.
3  *      All rights reserved.
4  *
5  * By using this file, you agree to the terms and conditions set
6  * forth in the LICENSE file which can be found at the top level of
7  * the sendmail distribution.
8  *
9  */
10
11 /*
12 **  Compile this program using a command line similar to:
13 **      cc -O -L../OBJ/libsm -o b-strl b-strl.c -lsm
14 **  where "OBJ" is the name of the object directory for the platform
15 **  you are compiling on.
16 **  Then run the program:
17 **      ./b-strl
18 **  and read the output for results and how to interpret the results.
19 */
20
21 #include <sm/gen.h>
22 SM_RCSID("@(#)$Id: b-strl.c,v 1.24 2001/09/11 04:04:47 gshapiro Exp $")
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27 #include <sys/time.h>
28 #include <sm/string.h>
29
30 #define SRC_SIZE        512
31 #define toseconds(x, y) (x.tv_sec - y.tv_sec)
32 #define LOOPS   4000000L        /* initial number of loops */
33 #define MAXTIME 30L     /* "maximum" time to run single test */
34
35 void
36 fatal(str)
37         char *str;
38 {
39         perror(str);
40         exit(1);
41 }
42
43 void
44 purpose()
45 {
46         printf("This program benchmarks the performance differences between\n");
47         printf("strlcpy() and sm_strlcpy(), and strlcat() and sm_strlcat().\n");
48         printf("These tests may take several minutes to complete.\n");
49 }
50
51 int
52 main(argc, argv)
53         int argc;
54         char *argv[];
55 {
56 #if !SM_CONF_STRL
57         printf("The configuration indicates the system needs the libsm\n");
58         printf("versions of strlcpy(3) and strlcat(3). Thus, performing\n");
59         printf("these tests will not be of much use.\n");
60         printf("If your OS has strlcpy(3) and strlcat(3) then set the macro\n");
61         printf("SM_CONF_STRL to 1 in your site.config.m4 file\n");
62         printf("(located in ../devtools/Site) and recompile this program.\n");
63 #else /* !SM_CONF_STRL */
64         int ch;
65         long a;
66         bool doit = false;
67         long loops = LOOPS;
68         long one, two;
69         struct timeval t1, t2;
70         char dest[SRC_SIZE], source[SRC_SIZE];
71
72 # define OPTIONS        "d"
73         while ((ch = getopt(argc, argv, OPTIONS)) != -1)
74         {
75                 switch ((char) ch)
76                 {
77                   case 'd':
78                         doit = true;
79                         break;
80
81                   default:
82                         break;
83                 }
84         }
85
86         if (!doit)
87         {
88                 purpose();
89                 printf("If you want to run it, specify -d as option.\n");
90                 return 0;
91         }
92
93         /*
94         **  Let's place a small string at the head of dest for
95         **  catenation to happen (it'll be ignored for the copy).
96         */
97         (void) sm_strlcpy(dest, "a small string at the start! ", SRC_SIZE - 1);
98
99         /*
100         **  Let's place a larger string into source for the catenation and
101         **  the copy.
102         */
103         (void) strlcpy(source,
104                 " This is the longer string that will be used for catenation and copying for the the performace testing. The longer the string being catenated or copied the greater the difference in measureable performance\n",
105                 SRC_SIZE - 1);
106
107         /* Run-time comments to the user */
108         purpose();
109         printf("\n");
110         printf("Test 1: strlcat() versus sm_strlcat()\n");
111
112 redo_cat:
113         if (gettimeofday(&t1, NULL) < 0)
114                 fatal("gettimeofday");
115
116         for (a = 0; a < loops; a++)
117                 strlcat(dest, source, SRC_SIZE - 1);
118
119         if (gettimeofday(&t2, NULL) < 0)
120                 fatal("gettimeofday");
121
122         printf("\tstrlcat() result: %ld seconds\n", one = toseconds(t2, t1));
123
124         if (gettimeofday(&t1, NULL) < 0)
125                 fatal("gettimeofday");
126
127         for (a = 0; a < loops; a++)
128                 sm_strlcat(dest, source, SRC_SIZE - 1);
129
130         if (gettimeofday(&t2, NULL) < 0)
131                 fatal("gettimeofday");
132
133         printf("\tsm_strlcat() result: %ld seconds\n", two = toseconds(t2, t1));
134
135         if (one - two >= -2 && one - two <= 2)
136         {
137                 loops += loops;
138                 if (loops < 0L || one > MAXTIME)
139                 {
140                         printf("\t\t** results too close: no decision\n");
141                 }
142                 else
143                 {
144                         printf("\t\t** results too close redoing test %ld times **\n",
145                                 loops);
146                         goto redo_cat;
147                 }
148         }
149
150         printf("\n");
151         printf("Test 2: strlcpy() versus sm_strlpy()\n");
152         loops = LOOPS;
153 redo_cpy:
154         if (gettimeofday(&t1, NULL) < 0)
155                 fatal("gettimeofday");
156
157         for (a = 0; a < loops; a++)
158                 strlcpy(dest, source, SRC_SIZE - 1);
159
160         if (gettimeofday(&t2, NULL) < 0)
161                 fatal("gettimeofday");
162
163         printf("\tstrlcpy() result: %ld seconds\n", one = toseconds(t2, t1));
164
165         if (gettimeofday(&t1, NULL) < 0)
166                 fatal("gettimeofday");
167
168         for (a = 0; a < loops; a++)
169                 sm_strlcpy(dest, source, SRC_SIZE - 1);
170
171         if (gettimeofday(&t2, NULL) < 0)
172                 fatal("gettimeofday");
173
174         printf("\tsm_strlcpy() result: %ld seconds\n", two = toseconds(t2, t1));
175
176         if (one - two >= -2 && one - two <= 2)
177         {
178                 loops += loops;
179                 if (loops < 0L || one > MAXTIME)
180                 {
181                         printf("\t\t** results too close: no decision\n");
182                 }
183                 else
184                 {
185                         printf("\t\t** results too close redoing test %ld times **\n",
186                                 loops);
187                         goto redo_cpy;
188                 }
189         }
190
191         printf("\n\n");
192         printf("Interpreting the results:\n");
193         printf("\tFor differences larger than 2 seconds, the lower value is\n");
194         printf("\tbetter and that function should be used for performance\n");
195         printf("\treasons.\n\n");
196         printf("This program will re-run the tests when the difference is\n");
197         printf("less than 2 seconds.\n");
198         printf("The result will vary depending on the compiler optimization\n");        printf("level used. Compiling the sendmail libsm library with a\n");
199         printf("better optimization level can change the results.\n");
200 #endif /* !SM_CONF_STRL  */
201         return 0;
202 }