Add support for calculating the CPU usage while doing crypto.
This is useful for showing the gains through HW acceleration
other than just speed.  It is best used with the '-elapsed' option
to get real-world values.

Currently only linux supports cpu calculations,  but it should be easy
to add get_cpu/calc_cpu functions for other OS's.

Also includes a few compile time warning fixes.

---
 apps/speed.c |  215 ++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 172 insertions(+), 43 deletions(-)

diff --git a/apps/speed.c b/apps/speed.c
index 52bc481..a4bef32 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -257,6 +257,80 @@ static SIGRETTYPE sig_done(int sig)
 #define START  0
 #define STOP   1
 
+#ifdef __linux__
+
+#define HAVE_CPU_USAGE 1
+
+/*
+ * record CPU usage as well
+ */
+
+struct cpu_stat {
+       unsigned int    user;
+       unsigned int    nice;
+       unsigned int    system;
+       unsigned int    idle;
+       unsigned int    total;
+};
+
+static unsigned int cpu_usage[ALGOR_NUM][SIZE_NUM];
+static unsigned int rsa_cpu_usage[RSA_NUM][2];
+static unsigned int dsa_cpu_usage[DSA_NUM][2];
+static struct cpu_stat cpu_start, cpu_finish;
+
+static void
+get_cpu(int s)
+{
+       FILE *fp = NULL;
+       unsigned char   buf[80];
+       struct cpu_stat *st = s == START ? &cpu_start : &cpu_finish;
+
+       memset(st, 0, sizeof(*st));
+
+       if (fp == NULL)
+               fp = fopen("/proc/stat", "r");
+       if (!fp)
+               return;
+       if (fseek(fp, 0, SEEK_SET) == -1) {
+               fclose(fp);
+               return;
+       }
+       if (fscanf(fp, "%s %d %d %d %d", &buf[0], &st->user, &st->nice,
+                       &st->system, &st->idle) == 5)
+               st->total = st->user + st->nice + st->system + st->idle;
+       fclose(fp);
+}
+
+static unsigned int
+calc_cpu()
+{
+       unsigned int total, res;
+
+       total  = cpu_finish.total - cpu_start.total;
+       if (total <= 0)
+               return 0;
+#if 1 // busy
+       res   = ((cpu_finish.system + cpu_finish.user + cpu_finish.nice) -
+                        (cpu_start.system + cpu_start.user + cpu_start.nice)) *
+                        100 / total;
+#endif
+#if 0 // system
+       res   = (cpu_finish.system - cpu_start.system) * 100 / total;
+#endif
+#if 0 // user
+       res   = (cpu_finish.user   - cpu_start.user)   * 100 / total;
+#endif
+#if 0 // nice
+       res   = (cpu_finish.nice   - cpu_start.nice)   * 100 / total;
+#endif
+#if 0 // idle
+       res   = (cpu_finish.idle   - cpu_start.idle)   * 100 / total;
+#endif
+       return(res);
+}
+
+#endif
+
 #if defined(_WIN32)
 
 #define SIGALRM
@@ -273,6 +347,9 @@ static DWORD WINAPI sleepy(VOID *arg)
 
 static double Time_F(int s)
        {
+       if (do_cpu)
+               get_cpu(s);
+
        if (s == START)
                {
                HANDLE  thr;
@@ -294,6 +371,8 @@ static double Time_F(int s)
 
 static double Time_F(int s)
        {
+       if (do_cpu)
+               get_cpu(s);
        return app_tminterval(s,usertime);
        }
 #endif
@@ -316,6 +395,14 @@ static void *KDF1_SHA1(const void *in, size_t inlen, void 
*out, size_t *outlen)
 #endif /* OPENSSL_NO_ECDH */
 
 
+static int do_cpu = 0;
+#ifndef HAVE_CPU_USAGE
+/* stub out the cpu functions if we do not support it */
+static void get_cpu(int s) {}
+static unsigned int calc_cpu() { return 0; }
+#endif
+
+
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
@@ -670,6 +757,14 @@ int MAIN(int argc, char **argv)
                        j--;    /* Otherwise, -elapsed gets confused with
                                   an algorithm. */
                        }
+#ifdef HAVE_CPU_USAGE
+               else if ((argc > 0) && (strcmp(*argv,"-cpu") == 0))
+                       {
+                       do_cpu = 1;
+                       j--;    /* Otherwise, -cpu gets confused with
+                                  an algorithm. */
+                       }
+#endif
                else if ((argc > 0) && (strcmp(*argv,"-evp") == 0))
                        {
                        argc--;
@@ -1106,6 +1201,9 @@ int MAIN(int argc, char **argv)
 #ifdef HAVE_FORK
                        BIO_printf(bio_err,"-multi n        run n benchmarks in 
parallel.\n");
 #endif
+#ifdef HAVE_CPU_USAGE
+                       BIO_printf(bio_err,"-cpu            calculate cpu 
utilisation.\n");
+#endif
                        goto end;
                        }
                argc--;
@@ -1113,11 +1211,6 @@ int MAIN(int argc, char **argv)
                j++;
                }
 
-#ifdef HAVE_FORK
-       if(multi && do_multi(multi))
-               goto show_res;
-#endif
-
        if (j == 0)
                {
                for (i=0; i<ALGOR_NUM; i++)
@@ -1457,6 +1550,11 @@ int MAIN(int argc, char **argv)
 #endif
 #endif /* SIGALRM */
 
+#ifdef HAVE_FORK /* Do this as late as possible to give better CPU readings */
+       if(multi && do_multi(multi))
+               goto show_res;
+#endif
+
 #ifndef OPENSSL_NO_MD2
        if (doit[D_MD2])
                {
@@ -1903,8 +2001,6 @@ int MAIN(int argc, char **argv)
                                /* -O3 -fschedule-insns messes up an
                                 * optimization here!  names[D_EVP]
                                 * somehow becomes NULL */
-                               print_message(names[D_EVP],save_count,
-                                       lengths[j]);
 
                                EVP_CIPHER_CTX_init(&ctx);
                                if(decrypt)
@@ -1913,6 +2009,9 @@ int MAIN(int argc, char **argv)
                                        
EVP_EncryptInit_ex(&ctx,evp_cipher,NULL,key16,iv);
                                EVP_CIPHER_CTX_set_padding(&ctx, 0);
 
+                               print_message(names[D_EVP],save_count,
+                                       lengths[j]);
+
                                Time_F(START);
                                if(decrypt)
                                        for (count=0,run=1; 
COND(save_count*4*lengths[0]/lengths[j]); count++)
@@ -1977,6 +2076,8 @@ int MAIN(int argc, char **argv)
                                        }
                                }
                        d=Time_F(STOP);
+                       if (do_cpu)
+                               rsa_cpu_usage[j][0] = calc_cpu();
                        BIO_printf(bio_err,mr ? "+R1:%ld:%d:%.2f\n"
                                   : "%ld %d bit private RSA's in %.2fs\n",
                                   count,rsa_bits[j],d);
@@ -2012,6 +2113,8 @@ int MAIN(int argc, char **argv)
                                        }
                                }
                        d=Time_F(STOP);
+                       if (do_cpu)
+                               rsa_cpu_usage[j][1] = calc_cpu();
                        BIO_printf(bio_err,mr ? "+R2:%ld:%d:%.2f\n"
                                   : "%ld %d bit public RSA's in %.2fs\n",
                                   count,rsa_bits[j],d);
@@ -2071,6 +2174,8 @@ int MAIN(int argc, char **argv)
                                        }
                                }
                        d=Time_F(STOP);
+                       if (do_cpu)
+                               dsa_cpu_usage[j][0] = calc_cpu();
                        BIO_printf(bio_err,mr ? "+R3:%ld:%d:%.2f\n"
                                   : "%ld %d bit DSA signs in %.2fs\n",
                                   count,dsa_bits[j],d);
@@ -2106,6 +2211,8 @@ int MAIN(int argc, char **argv)
                                        }
                                }
                        d=Time_F(STOP);
+                       if (do_cpu)
+                               dsa_cpu_usage[j][1] = calc_cpu();
                        BIO_printf(bio_err,mr ? "+R4:%ld:%d:%.2f\n"
                                   : "%ld %d bit DSA verify in %.2fs\n",
                                   count,dsa_bits[j],d);
@@ -2371,14 +2478,23 @@ show_res:
                        fprintf(stdout,"The 'numbers' are in 1000s of bytes per 
second processed.\n"); 
                        fprintf(stdout,"type        ");
                        }
-               for (j=0;  j<SIZE_NUM; j++)
+               for (j=0;  j<SIZE_NUM; j++) {
                        fprintf(stdout,mr ? ":%d" : "%7d bytes",lengths[j]);
+                       if (do_cpu && !mr)
+                               fprintf(stdout, " /cpu");
+               }
                fprintf(stdout,"\n");
                }
 
        for (k=0; k<ALGOR_NUM; k++)
                {
                if (!doit[k]) continue;
+               if (k == D_EVP) {
+                       if (evp_cipher)
+                               names[D_EVP]=OBJ_nid2ln(evp_cipher->nid);
+                       else
+                               names[D_EVP]=OBJ_nid2ln(evp_md->type);
+               }
                if(mr)
                        fprintf(stdout,"+F:%d:%s",k,names[k]);
                else
@@ -2389,6 +2505,8 @@ show_res:
                                fprintf(stdout," %11.2fk",results[k][j]/1e3);
                        else
                                fprintf(stdout,mr ? ":%.2f" : " %11.2f 
",results[k][j]);
+                       if (do_cpu)
+                               fprintf(stdout, mr ? "/%d" : "/%%%-3d", 
cpu_usage[k][j]);
                        }
                fprintf(stdout,"\n");
                }
@@ -2403,13 +2521,18 @@ show_res:
                        j=0;
                        }
                if(mr)
-                       fprintf(stdout,"+F2:%u:%u:%f:%f\n",
-                               k,rsa_bits[k],rsa_results[k][0],
-                               rsa_results[k][1]);
+                       fprintf(stdout,"+F2:%u:%u:%f", 
k,rsa_bits[k],rsa_results[k][0]);
                else
-                       fprintf(stdout,"rsa %4u bits %8.6fs %8.6fs %8.1f 
%8.1f\n",
-                               rsa_bits[k],rsa_results[k][0],rsa_results[k][1],
-                               1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+                       fprintf(stdout,"rsa %4u bits 
%8.6fs",rsa_bits[k],rsa_results[k][0]);
+               if (do_cpu)
+                       fprintf(stdout, mr ? "/%d": "/%%%-3d", 
rsa_cpu_usage[k][0]);
+               fprintf(stdout, mr ? ":%f" : " %8.6fs", rsa_results[k][1]);
+               if (do_cpu)
+                       fprintf(stdout, mr ? "/%d": "/%%%-3d", 
rsa_cpu_usage[k][1]);
+               if(!mr)
+                       fprintf(stdout, " %8.1f %8.1f",
+                                       
1.0/rsa_results[k][0],1.0/rsa_results[k][1]);
+               fprintf(stdout, "\n");
                }
 #endif
 #ifndef OPENSSL_NO_DSA
@@ -2423,12 +2546,18 @@ show_res:
                        j=0;
                        }
                if(mr)
-                       fprintf(stdout,"+F3:%u:%u:%f:%f\n",
-                               
k,dsa_bits[k],dsa_results[k][0],dsa_results[k][1]);
+                       fprintf(stdout,"+F3:%u:%u:%f", 
k,dsa_bits[k],dsa_results[k][0]);
                else
-                       fprintf(stdout,"dsa %4u bits %8.6fs %8.6fs %8.1f 
%8.1f\n",
-                               dsa_bits[k],dsa_results[k][0],dsa_results[k][1],
-                               1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+                       fprintf(stdout,"dsa %4u bits 
%8.6fs",dsa_bits[k],dsa_results[k][0]);
+               if (do_cpu)
+                       fprintf(stdout, mr ? "/%d": "/%%%-3d", 
dsa_cpu_usage[k][0]);
+               fprintf(stdout, mr ? ":%f" : " %8.6fs", dsa_results[k][1]);
+               if (do_cpu)
+                       fprintf(stdout, mr ? "/%d": "/%%%-3d", 
dsa_cpu_usage[k][1]);
+               if(!mr)
+                       fprintf(stdout, " %8.1f %8.1f",
+                                       
1.0/dsa_results[k][0],1.0/dsa_results[k][1]);
+               fprintf(stdout, "\n");
                }
 #endif
 #ifndef OPENSSL_NO_ECDSA
@@ -2553,8 +2682,10 @@ static void pkey_print_message(const char *str, const 
char *str2, long num,
 
 static void print_result(int alg,int run_no,int count,double time_used)
        {
+       if (do_cpu)
+           cpu_usage[alg][run_no] = calc_cpu();
        BIO_printf(bio_err,mr ? "+R:%d:%s:%f\n"
-                  : "%d %s's in %.2fs\n",count,names[alg],time_used);
+                  : "%d %s's in %.2fs\n",count,names[alg],time_used);
        results[alg][run_no]=((double)count)/time_used*lengths[run_no];
        }
 
@@ -2600,7 +2731,10 @@ static int do_multi(int multi)
        fds=malloc(multi*sizeof *fds);
        for(n=0 ; n < multi ; ++n)
                {
-               pipe(fd);
+               if (pipe(fd) == -1) {
+                       fprintf(stderr, "pipe() failed: %s\n", strerror(errno));
+                       continue;
+               }
                fflush(stdout);
                fflush(stderr);
                if(fork())
@@ -2612,7 +2746,8 @@ static int do_multi(int multi)
                        {
                        close(fd[0]);
                        close(1);
-                       dup(fd[1]);
+                       if (dup(fd[1]) == -1)
+                               fprintf(stderr, "dup() failed: %s\n", 
strerror(errno));
                        close(fd[1]);
                        mr=1;
                        usertime=0;
@@ -2650,29 +2785,11 @@ static int do_multi(int multi)
                                p=buf+3;
                                alg=atoi(sstrsep(&p,sep));
                                sstrsep(&p,sep);
-                               for(j=0 ; j < SIZE_NUM ; ++j)
+                               for(j=0 ; j < SIZE_NUM ; ++j) {
+                                       if (do_cpu && strchr(p, '/'))
+                                               cpu_usage[alg][j] = 
atoi(strchr(p, '/') + 1);
                                        results[alg][j]+=atof(sstrsep(&p,sep));
                                }
-                       else if(!strncmp(buf,"+F2:",4))
-                               {
-                               int k;
-                               double d;
-                               
-                               p=buf+4;
-                               k=atoi(sstrsep(&p,sep));
-                               sstrsep(&p,sep);
-
-                               d=atof(sstrsep(&p,sep));
-                               if(n)
-                                       
rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
-                               else
-                                       rsa_results[k][0]=d;
-
-                               d=atof(sstrsep(&p,sep));
-                               if(n)
-                                       
rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
-                               else
-                                       rsa_results[k][1]=d;
                                }
                        else if(!strncmp(buf,"+F2:",4))
                                {
@@ -2683,12 +2800,18 @@ static int do_multi(int multi)
                                k=atoi(sstrsep(&p,sep));
                                sstrsep(&p,sep);
 
+                               /* before we move the token along */
+                               if (do_cpu && strchr(p, '/'))
+                                       rsa_cpu_usage[k][0] = atoi(strchr(p, 
'/') + 1);
                                d=atof(sstrsep(&p,sep));
                                if(n)
                                        
rsa_results[k][0]=1/(1/rsa_results[k][0]+1/d);
                                else
                                        rsa_results[k][0]=d;
 
+                               /* before we move the token along */
+                               if (do_cpu && strchr(p, '/'))
+                                       rsa_cpu_usage[k][1] = atoi(strchr(p, 
'/') + 1);
                                d=atof(sstrsep(&p,sep));
                                if(n)
                                        
rsa_results[k][1]=1/(1/rsa_results[k][1]+1/d);
@@ -2704,12 +2827,18 @@ static int do_multi(int multi)
                                k=atoi(sstrsep(&p,sep));
                                sstrsep(&p,sep);
 
+                               /* before we move the token along */
+                               if (do_cpu && strchr(p, '/'))
+                                       dsa_cpu_usage[k][0] = atoi(strchr(p, 
'/') + 1);
                                d=atof(sstrsep(&p,sep));
                                if(n)
                                        
dsa_results[k][0]=1/(1/dsa_results[k][0]+1/d);
                                else
                                        dsa_results[k][0]=d;
 
+                               /* before we move the token along */
+                               if (do_cpu && strchr(p, '/'))
+                                       dsa_cpu_usage[k][1] = atoi(strchr(p, 
'/') + 1);
                                d=atof(sstrsep(&p,sep));
                                if(n)
                                        
dsa_results[k][1]=1/(1/dsa_results[k][1]+1/d);
diff --git a/apps/speed.c b/apps/speed.c
index a4bef32..c6f5b0e 100644
--- a/apps/speed.c
+++ b/apps/speed.c
@@ -277,6 +277,7 @@ static unsigned int cpu_usage[ALGOR_NUM][SIZE_NUM];
 static unsigned int rsa_cpu_usage[RSA_NUM][2];
 static unsigned int dsa_cpu_usage[DSA_NUM][2];
 static struct cpu_stat cpu_start, cpu_finish;
+static int do_cpu = 0;
 
 static void
 get_cpu(int s)
@@ -395,7 +396,6 @@ static void *KDF1_SHA1(const void *in, size_t inlen, void 
*out, size_t *outlen)
 #endif /* OPENSSL_NO_ECDH */
 
 
-static int do_cpu = 0;
 #ifndef HAVE_CPU_USAGE
 /* stub out the cpu functions if we do not support it */
 static void get_cpu(int s) {}

-- 
David McCullough,  [email protected],  Ph:+61 734352815
McAfee - SnapGear  http://www.snapgear.com                http://www.uCdot.org
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to