140266059SGregory Neil Shapiro /*
25dd76dd0SGregory Neil Shapiro * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers.
340266059SGregory Neil Shapiro * All rights reserved.
440266059SGregory Neil Shapiro *
540266059SGregory Neil Shapiro * By using this file, you agree to the terms and conditions set
640266059SGregory Neil Shapiro * forth in the LICENSE file which can be found at the top level of
740266059SGregory Neil Shapiro * the sendmail distribution.
840266059SGregory Neil Shapiro *
940266059SGregory Neil Shapiro */
1040266059SGregory Neil Shapiro
1140266059SGregory Neil Shapiro /*
1240266059SGregory Neil Shapiro ** Compile this program using a command line similar to:
1340266059SGregory Neil Shapiro ** cc -O -L../OBJ/libsm -o b-strl b-strl.c -lsm
1440266059SGregory Neil Shapiro ** where "OBJ" is the name of the object directory for the platform
1540266059SGregory Neil Shapiro ** you are compiling on.
1640266059SGregory Neil Shapiro ** Then run the program:
1740266059SGregory Neil Shapiro ** ./b-strl
1840266059SGregory Neil Shapiro ** and read the output for results and how to interpret the results.
1940266059SGregory Neil Shapiro */
2040266059SGregory Neil Shapiro
2140266059SGregory Neil Shapiro #include <sm/gen.h>
224313cc83SGregory Neil Shapiro SM_RCSID("@(#)$Id: b-strl.c,v 1.26 2013-11-22 20:51:42 ca Exp $")
2340266059SGregory Neil Shapiro #include <stdio.h>
2440266059SGregory Neil Shapiro #include <stdlib.h>
2540266059SGregory Neil Shapiro #include <unistd.h>
2640266059SGregory Neil Shapiro #include <sys/types.h>
274e4196cbSGregory Neil Shapiro #include <sm/time.h>
2840266059SGregory Neil Shapiro #include <sm/string.h>
2940266059SGregory Neil Shapiro
3040266059SGregory Neil Shapiro #define SRC_SIZE 512
3140266059SGregory Neil Shapiro #define toseconds(x, y) (x.tv_sec - y.tv_sec)
3240266059SGregory Neil Shapiro #define LOOPS 4000000L /* initial number of loops */
3340266059SGregory Neil Shapiro #define MAXTIME 30L /* "maximum" time to run single test */
3440266059SGregory Neil Shapiro
3540266059SGregory Neil Shapiro void
3640266059SGregory Neil Shapiro fatal(str)
3740266059SGregory Neil Shapiro char *str;
3840266059SGregory Neil Shapiro {
3940266059SGregory Neil Shapiro perror(str);
4040266059SGregory Neil Shapiro exit(1);
4140266059SGregory Neil Shapiro }
4240266059SGregory Neil Shapiro
4340266059SGregory Neil Shapiro void
purpose()4440266059SGregory Neil Shapiro purpose()
4540266059SGregory Neil Shapiro {
4640266059SGregory Neil Shapiro printf("This program benchmarks the performance differences between\n");
4740266059SGregory Neil Shapiro printf("strlcpy() and sm_strlcpy(), and strlcat() and sm_strlcat().\n");
4840266059SGregory Neil Shapiro printf("These tests may take several minutes to complete.\n");
4940266059SGregory Neil Shapiro }
5040266059SGregory Neil Shapiro
5140266059SGregory Neil Shapiro int
main(argc,argv)5240266059SGregory Neil Shapiro main(argc, argv)
5340266059SGregory Neil Shapiro int argc;
5440266059SGregory Neil Shapiro char *argv[];
5540266059SGregory Neil Shapiro {
5640266059SGregory Neil Shapiro #if !SM_CONF_STRL
5740266059SGregory Neil Shapiro printf("The configuration indicates the system needs the libsm\n");
5840266059SGregory Neil Shapiro printf("versions of strlcpy(3) and strlcat(3). Thus, performing\n");
5940266059SGregory Neil Shapiro printf("these tests will not be of much use.\n");
6040266059SGregory Neil Shapiro printf("If your OS has strlcpy(3) and strlcat(3) then set the macro\n");
6140266059SGregory Neil Shapiro printf("SM_CONF_STRL to 1 in your site.config.m4 file\n");
6240266059SGregory Neil Shapiro printf("(located in ../devtools/Site) and recompile this program.\n");
6340266059SGregory Neil Shapiro #else /* !SM_CONF_STRL */
6440266059SGregory Neil Shapiro int ch;
6540266059SGregory Neil Shapiro long a;
6640266059SGregory Neil Shapiro bool doit = false;
6740266059SGregory Neil Shapiro long loops = LOOPS;
6840266059SGregory Neil Shapiro long one, two;
6940266059SGregory Neil Shapiro struct timeval t1, t2;
7040266059SGregory Neil Shapiro char dest[SRC_SIZE], source[SRC_SIZE];
7140266059SGregory Neil Shapiro
7240266059SGregory Neil Shapiro # define OPTIONS "d"
7340266059SGregory Neil Shapiro while ((ch = getopt(argc, argv, OPTIONS)) != -1)
7440266059SGregory Neil Shapiro {
7540266059SGregory Neil Shapiro switch ((char) ch)
7640266059SGregory Neil Shapiro {
7740266059SGregory Neil Shapiro case 'd':
7840266059SGregory Neil Shapiro doit = true;
7940266059SGregory Neil Shapiro break;
8040266059SGregory Neil Shapiro
8140266059SGregory Neil Shapiro default:
8240266059SGregory Neil Shapiro break;
8340266059SGregory Neil Shapiro }
8440266059SGregory Neil Shapiro }
8540266059SGregory Neil Shapiro
8640266059SGregory Neil Shapiro if (!doit)
8740266059SGregory Neil Shapiro {
8840266059SGregory Neil Shapiro purpose();
8940266059SGregory Neil Shapiro printf("If you want to run it, specify -d as option.\n");
9040266059SGregory Neil Shapiro return 0;
9140266059SGregory Neil Shapiro }
9240266059SGregory Neil Shapiro
9340266059SGregory Neil Shapiro /*
9440266059SGregory Neil Shapiro ** Let's place a small string at the head of dest for
9540266059SGregory Neil Shapiro ** catenation to happen (it'll be ignored for the copy).
9640266059SGregory Neil Shapiro */
9740266059SGregory Neil Shapiro (void) sm_strlcpy(dest, "a small string at the start! ", SRC_SIZE - 1);
9840266059SGregory Neil Shapiro
9940266059SGregory Neil Shapiro /*
10040266059SGregory Neil Shapiro ** Let's place a larger string into source for the catenation and
10140266059SGregory Neil Shapiro ** the copy.
10240266059SGregory Neil Shapiro */
10340266059SGregory Neil Shapiro (void) strlcpy(source,
104*d39bd2c1SGregory Neil Shapiro " This is the longer string that will be used for catenation and copying for the the performance testing. The longer the string being catenated or copied the greater the difference in measureable performance\n",
10540266059SGregory Neil Shapiro SRC_SIZE - 1);
10640266059SGregory Neil Shapiro
10740266059SGregory Neil Shapiro /* Run-time comments to the user */
10840266059SGregory Neil Shapiro purpose();
10940266059SGregory Neil Shapiro printf("\n");
11040266059SGregory Neil Shapiro printf("Test 1: strlcat() versus sm_strlcat()\n");
11140266059SGregory Neil Shapiro
11240266059SGregory Neil Shapiro redo_cat:
11340266059SGregory Neil Shapiro if (gettimeofday(&t1, NULL) < 0)
11440266059SGregory Neil Shapiro fatal("gettimeofday");
11540266059SGregory Neil Shapiro
11640266059SGregory Neil Shapiro for (a = 0; a < loops; a++)
11740266059SGregory Neil Shapiro strlcat(dest, source, SRC_SIZE - 1);
11840266059SGregory Neil Shapiro
11940266059SGregory Neil Shapiro if (gettimeofday(&t2, NULL) < 0)
12040266059SGregory Neil Shapiro fatal("gettimeofday");
12140266059SGregory Neil Shapiro
12240266059SGregory Neil Shapiro printf("\tstrlcat() result: %ld seconds\n", one = toseconds(t2, t1));
12340266059SGregory Neil Shapiro
12440266059SGregory Neil Shapiro if (gettimeofday(&t1, NULL) < 0)
12540266059SGregory Neil Shapiro fatal("gettimeofday");
12640266059SGregory Neil Shapiro
12740266059SGregory Neil Shapiro for (a = 0; a < loops; a++)
12840266059SGregory Neil Shapiro sm_strlcat(dest, source, SRC_SIZE - 1);
12940266059SGregory Neil Shapiro
13040266059SGregory Neil Shapiro if (gettimeofday(&t2, NULL) < 0)
13140266059SGregory Neil Shapiro fatal("gettimeofday");
13240266059SGregory Neil Shapiro
13340266059SGregory Neil Shapiro printf("\tsm_strlcat() result: %ld seconds\n", two = toseconds(t2, t1));
13440266059SGregory Neil Shapiro
13540266059SGregory Neil Shapiro if (one - two >= -2 && one - two <= 2)
13640266059SGregory Neil Shapiro {
13740266059SGregory Neil Shapiro loops += loops;
13840266059SGregory Neil Shapiro if (loops < 0L || one > MAXTIME)
13940266059SGregory Neil Shapiro {
14040266059SGregory Neil Shapiro printf("\t\t** results too close: no decision\n");
14140266059SGregory Neil Shapiro }
14240266059SGregory Neil Shapiro else
14340266059SGregory Neil Shapiro {
14440266059SGregory Neil Shapiro printf("\t\t** results too close redoing test %ld times **\n",
14540266059SGregory Neil Shapiro loops);
14640266059SGregory Neil Shapiro goto redo_cat;
14740266059SGregory Neil Shapiro }
14840266059SGregory Neil Shapiro }
14940266059SGregory Neil Shapiro
15040266059SGregory Neil Shapiro printf("\n");
15140266059SGregory Neil Shapiro printf("Test 2: strlcpy() versus sm_strlpy()\n");
15240266059SGregory Neil Shapiro loops = LOOPS;
15340266059SGregory Neil Shapiro redo_cpy:
15440266059SGregory Neil Shapiro if (gettimeofday(&t1, NULL) < 0)
15540266059SGregory Neil Shapiro fatal("gettimeofday");
15640266059SGregory Neil Shapiro
15740266059SGregory Neil Shapiro for (a = 0; a < loops; a++)
15840266059SGregory Neil Shapiro strlcpy(dest, source, SRC_SIZE - 1);
15940266059SGregory Neil Shapiro
16040266059SGregory Neil Shapiro if (gettimeofday(&t2, NULL) < 0)
16140266059SGregory Neil Shapiro fatal("gettimeofday");
16240266059SGregory Neil Shapiro
16340266059SGregory Neil Shapiro printf("\tstrlcpy() result: %ld seconds\n", one = toseconds(t2, t1));
16440266059SGregory Neil Shapiro
16540266059SGregory Neil Shapiro if (gettimeofday(&t1, NULL) < 0)
16640266059SGregory Neil Shapiro fatal("gettimeofday");
16740266059SGregory Neil Shapiro
16840266059SGregory Neil Shapiro for (a = 0; a < loops; a++)
16940266059SGregory Neil Shapiro sm_strlcpy(dest, source, SRC_SIZE - 1);
17040266059SGregory Neil Shapiro
17140266059SGregory Neil Shapiro if (gettimeofday(&t2, NULL) < 0)
17240266059SGregory Neil Shapiro fatal("gettimeofday");
17340266059SGregory Neil Shapiro
17440266059SGregory Neil Shapiro printf("\tsm_strlcpy() result: %ld seconds\n", two = toseconds(t2, t1));
17540266059SGregory Neil Shapiro
17640266059SGregory Neil Shapiro if (one - two >= -2 && one - two <= 2)
17740266059SGregory Neil Shapiro {
17840266059SGregory Neil Shapiro loops += loops;
17940266059SGregory Neil Shapiro if (loops < 0L || one > MAXTIME)
18040266059SGregory Neil Shapiro {
18140266059SGregory Neil Shapiro printf("\t\t** results too close: no decision\n");
18240266059SGregory Neil Shapiro }
18340266059SGregory Neil Shapiro else
18440266059SGregory Neil Shapiro {
18540266059SGregory Neil Shapiro printf("\t\t** results too close redoing test %ld times **\n",
18640266059SGregory Neil Shapiro loops);
18740266059SGregory Neil Shapiro goto redo_cpy;
18840266059SGregory Neil Shapiro }
18940266059SGregory Neil Shapiro }
19040266059SGregory Neil Shapiro
19140266059SGregory Neil Shapiro printf("\n\n");
19240266059SGregory Neil Shapiro printf("Interpreting the results:\n");
19340266059SGregory Neil Shapiro printf("\tFor differences larger than 2 seconds, the lower value is\n");
19440266059SGregory Neil Shapiro printf("\tbetter and that function should be used for performance\n");
19540266059SGregory Neil Shapiro printf("\treasons.\n\n");
19640266059SGregory Neil Shapiro printf("This program will re-run the tests when the difference is\n");
19740266059SGregory Neil Shapiro printf("less than 2 seconds.\n");
19840266059SGregory Neil Shapiro printf("The result will vary depending on the compiler optimization\n"); printf("level used. Compiling the sendmail libsm library with a\n");
19940266059SGregory Neil Shapiro printf("better optimization level can change the results.\n");
20040266059SGregory Neil Shapiro #endif /* !SM_CONF_STRL */
20140266059SGregory Neil Shapiro return 0;
20240266059SGregory Neil Shapiro }
203