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.

Overview : http://www.mail-archive.com/openssl-dev@openssl.org/msg26096.html

-- 
David McCullough,  david_mccullo...@securecomputing.com,  Ph:+61 734352815
McAfee - SnapGear  http://www.snapgear.com                http://www.uCdot.org

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) {}
-- 
1.6.0.4

Reply via email to