190792Sgshapiro/* 2261363Sgshapiro * Copyright (c) 2000-2001 Proofpoint, Inc. and its suppliers. 390792Sgshapiro * All rights reserved. 490792Sgshapiro * 590792Sgshapiro * By using this file, you agree to the terms and conditions set 690792Sgshapiro * forth in the LICENSE file which can be found at the top level of 790792Sgshapiro * the sendmail distribution. 890792Sgshapiro * 990792Sgshapiro */ 1090792Sgshapiro 1190792Sgshapiro/* 1290792Sgshapiro** Compile this program using a command line similar to: 1390792Sgshapiro** cc -O -L../OBJ/libsm -o b-strl b-strl.c -lsm 1490792Sgshapiro** where "OBJ" is the name of the object directory for the platform 1590792Sgshapiro** you are compiling on. 1690792Sgshapiro** Then run the program: 1790792Sgshapiro** ./b-strl 1890792Sgshapiro** and read the output for results and how to interpret the results. 1990792Sgshapiro*/ 2090792Sgshapiro 2190792Sgshapiro#include <sm/gen.h> 22266692SgshapiroSM_RCSID("@(#)$Id: b-strl.c,v 1.26 2013-11-22 20:51:42 ca Exp $") 2390792Sgshapiro#include <stdio.h> 2490792Sgshapiro#include <stdlib.h> 2590792Sgshapiro#include <unistd.h> 2690792Sgshapiro#include <sys/types.h> 27157001Sgshapiro#include <sm/time.h> 2890792Sgshapiro#include <sm/string.h> 2990792Sgshapiro 3090792Sgshapiro#define SRC_SIZE 512 3190792Sgshapiro#define toseconds(x, y) (x.tv_sec - y.tv_sec) 3290792Sgshapiro#define LOOPS 4000000L /* initial number of loops */ 3390792Sgshapiro#define MAXTIME 30L /* "maximum" time to run single test */ 3490792Sgshapiro 3590792Sgshapirovoid 3690792Sgshapirofatal(str) 3790792Sgshapiro char *str; 3890792Sgshapiro{ 3990792Sgshapiro perror(str); 4090792Sgshapiro exit(1); 4190792Sgshapiro} 4290792Sgshapiro 4390792Sgshapirovoid 4490792Sgshapiropurpose() 4590792Sgshapiro{ 4690792Sgshapiro printf("This program benchmarks the performance differences between\n"); 4790792Sgshapiro printf("strlcpy() and sm_strlcpy(), and strlcat() and sm_strlcat().\n"); 4890792Sgshapiro printf("These tests may take several minutes to complete.\n"); 4990792Sgshapiro} 5090792Sgshapiro 5190792Sgshapiroint 5290792Sgshapiromain(argc, argv) 5390792Sgshapiro int argc; 5490792Sgshapiro char *argv[]; 5590792Sgshapiro{ 5690792Sgshapiro#if !SM_CONF_STRL 5790792Sgshapiro printf("The configuration indicates the system needs the libsm\n"); 5890792Sgshapiro printf("versions of strlcpy(3) and strlcat(3). Thus, performing\n"); 5990792Sgshapiro printf("these tests will not be of much use.\n"); 6090792Sgshapiro printf("If your OS has strlcpy(3) and strlcat(3) then set the macro\n"); 6190792Sgshapiro printf("SM_CONF_STRL to 1 in your site.config.m4 file\n"); 6290792Sgshapiro printf("(located in ../devtools/Site) and recompile this program.\n"); 6390792Sgshapiro#else /* !SM_CONF_STRL */ 6490792Sgshapiro int ch; 6590792Sgshapiro long a; 6690792Sgshapiro bool doit = false; 6790792Sgshapiro long loops = LOOPS; 6890792Sgshapiro long one, two; 6990792Sgshapiro struct timeval t1, t2; 7090792Sgshapiro char dest[SRC_SIZE], source[SRC_SIZE]; 7190792Sgshapiro 7290792Sgshapiro# define OPTIONS "d" 7390792Sgshapiro while ((ch = getopt(argc, argv, OPTIONS)) != -1) 7490792Sgshapiro { 7590792Sgshapiro switch ((char) ch) 7690792Sgshapiro { 7790792Sgshapiro case 'd': 7890792Sgshapiro doit = true; 7990792Sgshapiro break; 8090792Sgshapiro 8190792Sgshapiro default: 8290792Sgshapiro break; 8390792Sgshapiro } 8490792Sgshapiro } 8590792Sgshapiro 8690792Sgshapiro if (!doit) 8790792Sgshapiro { 8890792Sgshapiro purpose(); 8990792Sgshapiro printf("If you want to run it, specify -d as option.\n"); 9090792Sgshapiro return 0; 9190792Sgshapiro } 9290792Sgshapiro 9390792Sgshapiro /* 9490792Sgshapiro ** Let's place a small string at the head of dest for 9590792Sgshapiro ** catenation to happen (it'll be ignored for the copy). 9690792Sgshapiro */ 9790792Sgshapiro (void) sm_strlcpy(dest, "a small string at the start! ", SRC_SIZE - 1); 9890792Sgshapiro 9990792Sgshapiro /* 10090792Sgshapiro ** Let's place a larger string into source for the catenation and 10190792Sgshapiro ** the copy. 10290792Sgshapiro */ 10390792Sgshapiro (void) strlcpy(source, 10490792Sgshapiro " 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", 10590792Sgshapiro SRC_SIZE - 1); 10690792Sgshapiro 10790792Sgshapiro /* Run-time comments to the user */ 10890792Sgshapiro purpose(); 10990792Sgshapiro printf("\n"); 11090792Sgshapiro printf("Test 1: strlcat() versus sm_strlcat()\n"); 11190792Sgshapiro 11290792Sgshapiroredo_cat: 11390792Sgshapiro if (gettimeofday(&t1, NULL) < 0) 11490792Sgshapiro fatal("gettimeofday"); 11590792Sgshapiro 11690792Sgshapiro for (a = 0; a < loops; a++) 11790792Sgshapiro strlcat(dest, source, SRC_SIZE - 1); 11890792Sgshapiro 11990792Sgshapiro if (gettimeofday(&t2, NULL) < 0) 12090792Sgshapiro fatal("gettimeofday"); 12190792Sgshapiro 12290792Sgshapiro printf("\tstrlcat() result: %ld seconds\n", one = toseconds(t2, t1)); 12390792Sgshapiro 12490792Sgshapiro if (gettimeofday(&t1, NULL) < 0) 12590792Sgshapiro fatal("gettimeofday"); 12690792Sgshapiro 12790792Sgshapiro for (a = 0; a < loops; a++) 12890792Sgshapiro sm_strlcat(dest, source, SRC_SIZE - 1); 12990792Sgshapiro 13090792Sgshapiro if (gettimeofday(&t2, NULL) < 0) 13190792Sgshapiro fatal("gettimeofday"); 13290792Sgshapiro 13390792Sgshapiro printf("\tsm_strlcat() result: %ld seconds\n", two = toseconds(t2, t1)); 13490792Sgshapiro 13590792Sgshapiro if (one - two >= -2 && one - two <= 2) 13690792Sgshapiro { 13790792Sgshapiro loops += loops; 13890792Sgshapiro if (loops < 0L || one > MAXTIME) 13990792Sgshapiro { 14090792Sgshapiro printf("\t\t** results too close: no decision\n"); 14190792Sgshapiro } 14290792Sgshapiro else 14390792Sgshapiro { 14490792Sgshapiro printf("\t\t** results too close redoing test %ld times **\n", 14590792Sgshapiro loops); 14690792Sgshapiro goto redo_cat; 14790792Sgshapiro } 14890792Sgshapiro } 14990792Sgshapiro 15090792Sgshapiro printf("\n"); 15190792Sgshapiro printf("Test 2: strlcpy() versus sm_strlpy()\n"); 15290792Sgshapiro loops = LOOPS; 15390792Sgshapiroredo_cpy: 15490792Sgshapiro if (gettimeofday(&t1, NULL) < 0) 15590792Sgshapiro fatal("gettimeofday"); 15690792Sgshapiro 15790792Sgshapiro for (a = 0; a < loops; a++) 15890792Sgshapiro strlcpy(dest, source, SRC_SIZE - 1); 15990792Sgshapiro 16090792Sgshapiro if (gettimeofday(&t2, NULL) < 0) 16190792Sgshapiro fatal("gettimeofday"); 16290792Sgshapiro 16390792Sgshapiro printf("\tstrlcpy() result: %ld seconds\n", one = toseconds(t2, t1)); 16490792Sgshapiro 16590792Sgshapiro if (gettimeofday(&t1, NULL) < 0) 16690792Sgshapiro fatal("gettimeofday"); 16790792Sgshapiro 16890792Sgshapiro for (a = 0; a < loops; a++) 16990792Sgshapiro sm_strlcpy(dest, source, SRC_SIZE - 1); 17090792Sgshapiro 17190792Sgshapiro if (gettimeofday(&t2, NULL) < 0) 17290792Sgshapiro fatal("gettimeofday"); 17390792Sgshapiro 17490792Sgshapiro printf("\tsm_strlcpy() result: %ld seconds\n", two = toseconds(t2, t1)); 17590792Sgshapiro 17690792Sgshapiro if (one - two >= -2 && one - two <= 2) 17790792Sgshapiro { 17890792Sgshapiro loops += loops; 17990792Sgshapiro if (loops < 0L || one > MAXTIME) 18090792Sgshapiro { 18190792Sgshapiro printf("\t\t** results too close: no decision\n"); 18290792Sgshapiro } 18390792Sgshapiro else 18490792Sgshapiro { 18590792Sgshapiro printf("\t\t** results too close redoing test %ld times **\n", 18690792Sgshapiro loops); 18790792Sgshapiro goto redo_cpy; 18890792Sgshapiro } 18990792Sgshapiro } 19090792Sgshapiro 19190792Sgshapiro printf("\n\n"); 19290792Sgshapiro printf("Interpreting the results:\n"); 19390792Sgshapiro printf("\tFor differences larger than 2 seconds, the lower value is\n"); 19490792Sgshapiro printf("\tbetter and that function should be used for performance\n"); 19590792Sgshapiro printf("\treasons.\n\n"); 19690792Sgshapiro printf("This program will re-run the tests when the difference is\n"); 19790792Sgshapiro printf("less than 2 seconds.\n"); 19890792Sgshapiro printf("The result will vary depending on the compiler optimization\n"); printf("level used. Compiling the sendmail libsm library with a\n"); 19990792Sgshapiro printf("better optimization level can change the results.\n"); 20090792Sgshapiro#endif /* !SM_CONF_STRL */ 20190792Sgshapiro return 0; 20290792Sgshapiro} 203