/* 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); }