diff -r 000000000000 -r 6474c204b198 security/nss/cmd/libpkix/perf/nss_threads.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/security/nss/cmd/libpkix/perf/nss_threads.c Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,164 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +/* + * nssThreads.c + * + * NSS Performance Evaluation application (multi-threaded) + * + */ + +#include +#include + +#include "secutil.h" + +#include "nspr.h" +#include "prtypes.h" +#include "prtime.h" +#include "prlong.h" + +#include "pk11func.h" +#include "secasn1.h" +#include "cert.h" +#include "cryptohi.h" +#include "secoid.h" +#include "certdb.h" +#include "nss.h" + +typedef struct ThreadDataStr tData; + +struct ThreadDataStr { + CERTCertificate* cert; + PRIntervalTime duration; + PRUint32 iterations; +}; + +static void ThreadEntry(void* data) +{ + tData* tdata = (tData*) data; + PRIntervalTime duration = tdata->duration; + PRTime now = PR_Now(); + PRIntervalTime start = PR_IntervalNow(); + + PR_ASSERT(duration); + if (!duration) + { + return; + } + do { + SECStatus rv = CERT_VerifyCertificate + (CERT_GetDefaultCertDB(), + tdata->cert, + PR_TRUE, + certificateUsageEmailSigner, + now, + NULL, + NULL, + NULL); + if (rv != SECSuccess) + { + (void) fprintf(stderr, "Validation failed.\n"); + PORT_Assert(0); + return; + } + tdata->iterations ++; + } while ((PR_IntervalNow() - start) < duration); +} + +static void Test(CERTCertificate* cert, PRIntervalTime duration, PRUint32 threads) +{ + tData data; + tData** alldata; + PRIntervalTime starttime, endtime, elapsed; + PRUint32 msecs; + float total = 0; + PRThread** pthreads = NULL; + PRUint32 i = 0; + + data.duration = duration; + data.cert = cert; + data.iterations = 0; + + starttime = PR_IntervalNow(); + pthreads = (PRThread**)PR_Malloc(threads*sizeof (PRThread*)); + alldata = (tData**)PR_Malloc(threads*sizeof (tData*)); + for (i = 0; i < threads; i++) + { + alldata[i] = (tData*)PR_Malloc(sizeof (tData)); + *alldata[i] = data; + pthreads[i] = + PR_CreateThread(PR_USER_THREAD, + ThreadEntry, + (void*) alldata[i], + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0); + + } + for (i = 0; i < threads; i++) + { + tData* args = alldata[i]; + PR_JoinThread(pthreads[i]); + total += args->iterations; + PR_Free((void*)args); + } + PR_Free((void*) pthreads); + PR_Free((void*) alldata); + endtime = PR_IntervalNow(); + + endtime = PR_IntervalNow(); + elapsed = endtime - starttime; + msecs = PR_IntervalToMilliseconds(elapsed); + total /= msecs; + total *= 1000; + (void) fprintf(stdout, "%f operations per second.\n", total); +} + + +static void finish(char* message, int code) +{ + (void) printf(message); + exit(code); +} + +static void usage(char* progname) +{ + (void) printf("Usage : %s \n\n", + progname); + finish("", 0); +} + +int nss_threads(int argc, char** argv) +{ + SECStatus rv = SECSuccess; + CERTCertDBHandle *handle = NULL; + CERTCertificate* cert = NULL; + PRIntervalTime duration = PR_SecondsToInterval(1); + PRUint32 threads = 1; + if (argc != 4) + { + usage(argv[0]); + } + if (atoi(argv[1]) > 0) + { + duration = PR_SecondsToInterval(atoi(argv[1])); + } + if (atoi(argv[2]) > 0) + { + threads = atoi(argv[2]); + } + + handle = CERT_GetDefaultCertDB(); + PR_ASSERT(handle); + cert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]); + if (!cert) + { + finish("Unable to find certificate.\n", 1); + } + Test(cert, duration, threads); + + CERT_DestroyCertificate(cert); + return (0); +}