summaryrefslogtreecommitdiff
path: root/security
diff options
context:
space:
mode:
authoralexei.volkov.bugs%sun.com <devnull@localhost>2005-03-29 22:32:22 +0000
committeralexei.volkov.bugs%sun.com <devnull@localhost>2005-03-29 22:32:22 +0000
commit651d511f19447f5e5ae1a402d97a277e7dd6cb69 (patch)
tree9475ed6eaff44f84eb7e56488a8a9161c60501b5 /security
parent48965ccd9ac61aac348e0b4e7b8cdc62e0e669cc (diff)
downloadnss-hg-651d511f19447f5e5ae1a402d97a277e7dd6cb69.tar.gz
fix for bug 287625: rsaperf should run multithreaded
Diffstat (limited to 'security')
-rw-r--r--security/nss/cmd/rsaperf/rsaperf.c169
1 files changed, 123 insertions, 46 deletions
diff --git a/security/nss/cmd/rsaperf/rsaperf.c b/security/nss/cmd/rsaperf/rsaperf.c
index e9483803d..c714d82e7 100644
--- a/security/nss/cmd/rsaperf/rsaperf.c
+++ b/security/nss/cmd/rsaperf/rsaperf.c
@@ -47,6 +47,7 @@
#define MAX_RSA_MODULUS_BYTES (1024/8)
#define DEFAULT_ITERS 10
#define DEFAULT_DURATION 10
+#define DEFAULT_THREADS 1
extern NSSLOWKEYPrivateKey * getDefaultRSAPrivateKey(void);
extern NSSLOWKEYPublicKey * getDefaultRSAPublicKey(void);
@@ -54,9 +55,9 @@ extern NSSLOWKEYPublicKey * getDefaultRSAPublicKey(void);
typedef struct TimingContextStr TimingContext;
struct TimingContextStr {
- int64 start;
- int64 end;
- int64 interval;
+ PRTime start;
+ PRTime end;
+ PRTime interval;
long days;
int hours;
@@ -66,20 +67,20 @@ struct TimingContextStr {
};
TimingContext *CreateTimingContext(void) {
- return PR_Malloc(sizeof(TimingContext));
+ return PORT_Alloc(sizeof(TimingContext));
}
void DestroyTimingContext(TimingContext *ctx) {
- PR_Free(ctx);
+ PORT_Free(ctx);
}
-void TimingBegin(TimingContext *ctx) {
- ctx->start = PR_Now();
+void TimingBegin(TimingContext *ctx, PRTime begin) {
+ ctx->start = begin;
}
static void timingUpdate(TimingContext *ctx) {
- int64 tmp, remaining;
- int64 L1000,L60,L24;
+ PRInt64 tmp, remaining;
+ PRInt64 L1000,L60,L24;
LL_I2L(L1000,1000);
LL_I2L(L60,60);
@@ -101,15 +102,15 @@ static void timingUpdate(TimingContext *ctx) {
LL_L2I(ctx->days, remaining);
}
-void TimingEnd(TimingContext *ctx) {
- ctx->end = PR_Now();
+void TimingEnd(TimingContext *ctx, PRTime end) {
+ ctx->end = end;
LL_SUB(ctx->interval, ctx->end, ctx->start);
PORT_Assert(LL_GE_ZERO(ctx->interval));
timingUpdate(ctx);
}
void TimingDivide(TimingContext *ctx, int divisor) {
- int64 tmp;
+ PRInt64 tmp;
LL_I2L(tmp, divisor);
LL_DIV(ctx->interval, ctx->interval, tmp);
@@ -151,8 +152,8 @@ char *TimingGenerateString(TimingContext *ctx) {
void
Usage(char *progName)
{
- fprintf(stderr, "Usage: %s [-d certdir] [-i iterations | -p period] [-s | -e]"
- " -n nickname\n",
+ fprintf(stderr, "Usage: %s [-d certdir] [-t threads] [-i iterations | -p period] "
+ "[-s | -e] -n nickname\n",
progName);
fprintf(stderr, "%-20s Cert database directory (default is ~/.netscape)\n",
"-d certdir");
@@ -160,6 +161,7 @@ Usage(char *progName)
fprintf(stderr, "%-20s How many seconds to run\n", "-p period");
fprintf(stderr, "%-20s Perform signing (private key) operations\n", "-s");
fprintf(stderr, "%-20s Perform encryption (public key) operations\n", "-e");
+ fprintf(stderr, "%-20s Number of execution threads\n", "-t threads(default 1)");
fprintf(stderr, "%-20s Nickname of certificate or key\n", "-n nickname");
exit(-1);
}
@@ -226,6 +228,57 @@ typedef SECStatus (* RSAOp)(void * key,
unsigned char * output,
unsigned char * input);
+typedef struct ThreadRunDataStr ThreadRunData;
+
+struct ThreadRunDataStr {
+ const PRBool *doIters;
+ const void *rsaKey;
+ const unsigned char *buf;
+ RSAOp fn;
+ int seconds;
+ long iters;
+ long iterRes;
+ PRErrorCode errNum;
+ SECStatus status;
+ PRTime tstart;
+ PRTime tstop;
+};
+
+
+void ThreadExecFunction(void *data)
+{
+ ThreadRunData *tdata = (ThreadRunData*)data;
+ unsigned char buf2[1024];
+
+ tdata->status = SECSuccess;
+ tdata->tstart = PR_Now();
+ if (*tdata->doIters) {
+ long i = tdata->iters;
+ tdata->iterRes = tdata->iters;
+ while (i--) {
+ SECStatus rv = tdata->fn((void*)tdata->rsaKey, buf2, (unsigned char*)tdata->buf);
+ if (rv != SECSuccess) {
+ tdata->errNum = PORT_GetError();
+ tdata->status = rv;
+ return;
+ }
+ }
+ } else {
+ PRIntervalTime total = PR_SecondsToInterval(tdata->seconds);
+ PRIntervalTime start = PR_IntervalNow();
+ tdata->iterRes = 0;
+ while (PR_IntervalNow() - start < total) {
+ SECStatus rv = tdata->fn((void*)tdata->rsaKey, buf2, (unsigned char*)tdata->buf);
+ if (rv != SECSuccess) {
+ tdata->errNum = PORT_GetError();
+ tdata->status = rv;
+ return;
+ }
+ tdata->iterRes++;
+ }
+ }
+ tdata->tstop = PR_Now();
+}
int
main(int argc, char **argv)
@@ -253,13 +306,19 @@ main(int argc, char **argv)
int seconds = DEFAULT_DURATION;
PRBool doIters = PR_FALSE;
PRBool doTime = PR_FALSE;
+ int threadNum = DEFAULT_THREADS;
+ ThreadRunData ** runDataArr = NULL;
+ PRThread ** threadsArr = NULL;
+ int calcThreads = 0;
+ PRTime startTimeAcc = 0;
+ PRTime stopTimeAcc = 0;
progName = strrchr(argv[0], '/');
if (!progName)
progName = strrchr(argv[0], '\\');
progName = progName ? progName+1 : argv[0];
- optstate = PL_CreateOptState(argc, argv, "d:i:sen:p:");
+ optstate = PL_CreateOptState(argc, argv, "d:i:sen:p:t:");
while ((optstatus = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@@ -285,6 +344,9 @@ main(int argc, char **argv)
seconds = (atol(optstate->value)>0?atol(optstate->value):DEFAULT_DURATION);
doTime = PR_TRUE;
break;
+ case 't':
+ threadNum = (atoi(optstate->value) > 0) ? atoi(optstate->value) : DEFAULT_THREADS;
+ break;
}
}
if (optstatus == PL_OPT_BAD)
@@ -381,7 +443,7 @@ main(int argc, char **argv)
PRErrorCode errNum;
const char * errStr = NULL;
- errNum = PR_GetError();
+ errNum = PORT_GetError();
if (errNum)
errStr = SECU_Strerror(errNum);
else
@@ -393,38 +455,53 @@ main(int argc, char **argv)
}
/* printf("START\n"); */
-
- timeCtx = CreateTimingContext();
- TimingBegin(timeCtx);
- if (doIters) {
- i = iters;
- while (i--) {
- rv = fn(rsaKey, buf2, buf);
- if (rv != SECSuccess) {
- PRErrorCode errNum = PR_GetError();
- const char * errStr = SECU_Strerror(errNum);
- fprintf(stderr, "Error in RSA operation: %d : %s\n",
- errNum, errStr);
- exit(1);
- }
- }
- } else {
- PRIntervalTime total = PR_SecondsToInterval(seconds);
- PRIntervalTime start = PR_IntervalNow();
- iters = 0;
- while (PR_IntervalNow() - start < total) {
- rv = fn(rsaKey, buf2, buf);
- if (rv != SECSuccess) {
- PRErrorCode errNum = PR_GetError();
- const char * errStr = SECU_Strerror(errNum);
- fprintf(stderr, "Error in RSA operation: %d : %s\n",
- errNum, errStr);
- exit(1);
- }
- iters++;
+ threadsArr = (PRThread**)PORT_Alloc(threadNum*sizeof(PRThread*));
+ runDataArr = (ThreadRunData**)PORT_Alloc(threadNum*sizeof(ThreadRunData*));
+ for (i = 0;i < threadNum;i++) {
+ runDataArr[i] = (ThreadRunData*)PORT_Alloc(sizeof(ThreadRunData));
+ runDataArr[i]->fn = fn;
+ runDataArr[i]->buf = buf;
+ runDataArr[i]->doIters = &doIters;
+ runDataArr[i]->rsaKey = rsaKey;
+ runDataArr[i]->seconds = seconds;
+ runDataArr[i]->iters = iters;
+ threadsArr[i] =
+ PR_CreateThread(PR_USER_THREAD,
+ ThreadExecFunction,
+ (void*) runDataArr[i],
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_JOINABLE_THREAD,
+ 0);
+ }
+ iters = 0;
+ calcThreads = 0;
+ stopTimeAcc = startTimeAcc = 0;
+ for (i = 0;i < threadNum;i++, calcThreads++)
+ {
+ PR_JoinThread(threadsArr[i]);
+ if (runDataArr[i]->status != SECSuccess) {
+ const char * errStr = SECU_Strerror(runDataArr[i]->errNum);
+ fprintf(stderr, "Thread %d: Error in RSA operation: %d : %s\n",
+ i, runDataArr[i]->errNum, errStr);
+ calcThreads -= 1;
+ } else {
+ startTimeAcc += runDataArr[i]->tstart;
+ stopTimeAcc += runDataArr[i]->tstop;
+ iters += runDataArr[i]->iterRes;
}
+ PORT_Free((void*)runDataArr[i]);
}
- TimingEnd(timeCtx);
+ PORT_Free(runDataArr);
+ PORT_Free(threadsArr);
+
+ LL_DIV(startTimeAcc, startTimeAcc, (PRInt64)calcThreads);
+ LL_DIV(stopTimeAcc, stopTimeAcc, (PRInt64)calcThreads);
+
+ timeCtx = CreateTimingContext();
+ TimingBegin(timeCtx, startTimeAcc);
+ TimingEnd(timeCtx, stopTimeAcc);
+
printf("%ld iterations in %s\n",
iters, TimingGenerateString(timeCtx));
printf("%.2f operations/s .\n", ((double)(iters)*(double)1000000.0) / (double)timeCtx->interval );