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