nss_threads.c (4112B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* 5 * nssThreads.c 6 * 7 * NSS Performance Evaluation application (multi-threaded) 8 * 9 */ 10 11 #include <stdio.h> 12 #include <string.h> 13 14 #include "secutil.h" 15 16 #include "nspr.h" 17 #include "prtypes.h" 18 #include "prtime.h" 19 #include "prlong.h" 20 21 #include "pk11func.h" 22 #include "secasn1.h" 23 #include "cert.h" 24 #include "cryptohi.h" 25 #include "secoid.h" 26 #include "certdb.h" 27 #include "nss.h" 28 29 typedef struct ThreadDataStr tData; 30 31 struct ThreadDataStr { 32 CERTCertificate* cert; 33 PRIntervalTime duration; 34 PRUint32 iterations; 35 }; 36 37 static void 38 ThreadEntry(void* data) 39 { 40 tData* tdata = (tData*)data; 41 PRIntervalTime duration = tdata->duration; 42 PRTime now = PR_Now(); 43 PRIntervalTime start = PR_IntervalNow(); 44 45 PR_ASSERT(duration); 46 if (!duration) { 47 return; 48 } 49 do { 50 SECStatus rv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), 51 tdata->cert, 52 PR_TRUE, 53 certificateUsageEmailSigner, 54 now, 55 NULL, 56 NULL, 57 NULL); 58 if (rv != SECSuccess) { 59 (void)fprintf(stderr, "Validation failed.\n"); 60 PORT_Assert(0); 61 return; 62 } 63 tdata->iterations++; 64 } while ((PR_IntervalNow() - start) < duration); 65 } 66 67 static void 68 Test(CERTCertificate* cert, PRIntervalTime duration, PRUint32 threads) 69 { 70 tData data; 71 tData** alldata; 72 PRIntervalTime starttime, endtime, elapsed; 73 PRUint32 msecs; 74 float total = 0; 75 PRThread** pthreads = NULL; 76 PRUint32 i = 0; 77 78 data.duration = duration; 79 data.cert = cert; 80 data.iterations = 0; 81 82 starttime = PR_IntervalNow(); 83 pthreads = (PRThread**)PR_Malloc(threads * sizeof(PRThread*)); 84 alldata = (tData**)PR_Malloc(threads * sizeof(tData*)); 85 for (i = 0; i < threads; i++) { 86 alldata[i] = (tData*)PR_Malloc(sizeof(tData)); 87 *alldata[i] = data; 88 pthreads[i] = 89 PR_CreateThread(PR_USER_THREAD, 90 ThreadEntry, 91 (void*)alldata[i], 92 PR_PRIORITY_NORMAL, 93 PR_GLOBAL_THREAD, 94 PR_JOINABLE_THREAD, 95 0); 96 } 97 for (i = 0; i < threads; i++) { 98 tData* args = alldata[i]; 99 PR_JoinThread(pthreads[i]); 100 total += args->iterations; 101 PR_Free((void*)args); 102 } 103 PR_Free((void*)pthreads); 104 PR_Free((void*)alldata); 105 endtime = PR_IntervalNow(); 106 107 endtime = PR_IntervalNow(); 108 elapsed = endtime - starttime; 109 msecs = PR_IntervalToMilliseconds(elapsed); 110 total /= msecs; 111 total *= 1000; 112 (void)fprintf(stdout, "%f operations per second.\n", total); 113 } 114 115 static void 116 finish(char* message, int code) 117 { 118 (void)printf(message); 119 exit(code); 120 } 121 122 static void 123 usage(char* progname) 124 { 125 (void)printf("Usage : %s <duration> <threads> <certnickname>\n\n", 126 progname); 127 finish("", 0); 128 } 129 130 int 131 nss_threads(int argc, char** argv) 132 { 133 SECStatus rv = SECSuccess; 134 CERTCertDBHandle* handle = NULL; 135 CERTCertificate* cert = NULL; 136 PRIntervalTime duration = PR_SecondsToInterval(1); 137 PRUint32 threads = 1; 138 if (argc != 4) { 139 usage(argv[0]); 140 } 141 if (atoi(argv[1]) > 0) { 142 duration = PR_SecondsToInterval(atoi(argv[1])); 143 } 144 if (atoi(argv[2]) > 0) { 145 threads = atoi(argv[2]); 146 } 147 148 handle = CERT_GetDefaultCertDB(); 149 PR_ASSERT(handle); 150 cert = CERT_FindCertByNicknameOrEmailAddr(handle, argv[3]); 151 if (!cert) { 152 finish("Unable to find certificate.\n", 1); 153 } 154 Test(cert, duration, threads); 155 156 CERT_DestroyCertificate(cert); 157 return (0); 158 }