sdbthreadtst.c (7075B)
1 #if defined(XP_UNIX) 2 #include <unistd.h> 3 #endif 4 #include <stdio.h> 5 #include <nss.h> 6 #include <prtypes.h> 7 #include <prerr.h> 8 #include <prerror.h> 9 #include <prthread.h> 10 #include <pk11pub.h> 11 #include <keyhi.h> 12 13 #define MAX_THREAD_COUNT 100 14 15 /* globals */ 16 int THREAD_COUNT = 30; 17 int FAILED = 0; 18 int ERROR = 0; 19 int LOOP_COUNT = 100; 20 int KEY_SIZE = 3072; 21 int STACK_SIZE = 0; 22 int VERBOSE = 0; 23 char *NSSDIR = "."; 24 PRBool ISTOKEN = PR_TRUE; 25 CK_MECHANISM_TYPE MECHANISM = CKM_RSA_PKCS_KEY_PAIR_GEN; 26 27 void 28 usage(char *prog, char *error) 29 { 30 if (error) { 31 fprintf(stderr, "Bad Arguments: %s", error); 32 } 33 fprintf(stderr, "usage: %s [-l loop_count] [-t thread_count] " 34 "[-k key_size] [-s stack_size] [-d nss_dir] [-e] [-v] [-h]\n", 35 prog); 36 fprintf(stderr, " loop_count -- " 37 "number of keys to generate on each thread (default=%d)\n", 38 LOOP_COUNT); 39 fprintf(stderr, " thread_count -- " 40 "number of of concurrent threads to run (def=%d,max=%d)\n", 41 THREAD_COUNT, MAX_THREAD_COUNT); 42 fprintf(stderr, " key_size -- " 43 "rsa key size in bits (default=%d)\n", 44 KEY_SIZE); 45 fprintf(stderr, " stack_size -- " 46 "thread stack size in bytes, 0=optimal (default=%d)\n", 47 STACK_SIZE); 48 fprintf(stderr, " nss_dir -- " 49 "location of the nss directory (default=%s)\n", 50 NSSDIR); 51 fprintf(stderr, " -e use session keys rather than token keys\n"); 52 fprintf(stderr, " -v verbose, print progress indicators\n"); 53 fprintf(stderr, " -h print this message\n"); 54 exit(2); 55 } 56 57 void 58 create_key_loop(void *arg) 59 { 60 int i; 61 PK11SlotInfo *slot = PK11_GetInternalKeySlot(); 62 PK11RSAGenParams param; 63 int threadnumber = *(int *)arg; 64 int failures = 0; 65 int progress = 5; 66 PRIntervalTime epoch = PR_IntervalNow(); 67 param.keySizeInBits = KEY_SIZE; 68 param.pe = 0x10001L; 69 printf(" - thread %d starting\n", threadnumber); 70 progress = 30 / THREAD_COUNT; 71 if (progress < 2) 72 progress = 2; 73 for (i = 0; i < LOOP_COUNT; i++) { 74 SECKEYPrivateKey *privKey; 75 SECKEYPublicKey *pubKey; 76 privKey = PK11_GenerateKeyPair(slot, MECHANISM, ¶m, &pubKey, 77 ISTOKEN, PR_TRUE, NULL); 78 if (privKey == NULL) { 79 fprintf(stderr, 80 "keypair gen in thread %d failed %s\n", threadnumber, 81 PORT_ErrorToString(PORT_GetError())); 82 FAILED++; 83 failures++; 84 } 85 if (VERBOSE && (i % progress) == 0) { 86 PRIntervalTime current = PR_IntervalNow(); 87 PRIntervalTime interval = current - epoch; 88 int seconds = (interval / PR_TicksPerSecond()); 89 int mseconds = ((interval * 1000) / PR_TicksPerSecond()) - (seconds * 1000); 90 epoch = current; 91 printf(" - thread %d @ %d iterations %d.%03d sec\n", threadnumber, 92 i, seconds, mseconds); 93 } 94 if (ISTOKEN && privKey) { 95 SECKEY_DestroyPublicKey(pubKey); 96 SECKEY_DestroyPrivateKey(privKey); 97 } 98 } 99 PK11_FreeSlot(slot); 100 printf(" * thread %d ending with %d failures\n", threadnumber, failures); 101 return; 102 } 103 104 int 105 main(int argc, char **argv) 106 { 107 PRThread *thread[MAX_THREAD_COUNT]; 108 int threadnumber[MAX_THREAD_COUNT]; 109 int i; 110 PRStatus status; 111 SECStatus rv; 112 char *prog = *argv++; 113 char buf[2048]; 114 char *arg; 115 116 while ((arg = *argv++) != NULL) { 117 if (*arg == '-') { 118 switch (arg[1]) { 119 case 'l': 120 if (*argv == NULL) 121 usage(prog, "missing loop count"); 122 LOOP_COUNT = atoi(*argv++); 123 break; 124 case 'k': 125 if (*argv == NULL) 126 usage(prog, "missing key size"); 127 KEY_SIZE = atoi(*argv++); 128 break; 129 case 's': 130 if (*argv == NULL) 131 usage(prog, "missing stack size"); 132 STACK_SIZE = atoi(*argv++); 133 break; 134 case 't': 135 if (*argv == NULL) 136 usage(prog, "missing thread count"); 137 THREAD_COUNT = atoi(*argv++); 138 if (THREAD_COUNT > MAX_THREAD_COUNT) { 139 usage(prog, "max thread count exceeded"); 140 } 141 break; 142 case 'v': 143 VERBOSE = 1; 144 break; 145 case 'd': 146 if (*argv == NULL) 147 usage(prog, "missing directory"); 148 NSSDIR = *argv++; 149 break; 150 case 'e': 151 ISTOKEN = PR_FALSE; 152 break; 153 case 'h': 154 usage(prog, NULL); 155 break; 156 default: 157 snprintf(buf, sizeof(buf), "unknown option %c", arg[1]); 158 usage(prog, buf); 159 } 160 } else { 161 snprintf(buf, sizeof(buf), "unknown argument %s", arg); 162 usage(prog, buf); 163 } 164 } 165 /* initialize NSS */ 166 rv = NSS_InitReadWrite(NSSDIR); 167 if (rv != SECSuccess) { 168 fprintf(stderr, 169 "NSS_InitReadWrite(%s) failed(%s)\n", NSSDIR, 170 PORT_ErrorToString(PORT_GetError())); 171 exit(2); 172 } 173 174 /* need to initialize the database here if it's not already */ 175 176 printf("creating %d threads\n", THREAD_COUNT); 177 for (i = 0; i < THREAD_COUNT; i++) { 178 threadnumber[i] = i; 179 thread[i] = PR_CreateThread(PR_USER_THREAD, create_key_loop, 180 &threadnumber[i], PR_PRIORITY_NORMAL, 181 PR_GLOBAL_THREAD, 182 PR_JOINABLE_THREAD, STACK_SIZE); 183 if (thread[i] == NULL) { 184 ERROR++; 185 fprintf(stderr, 186 "PR_CreateThread failed iteration %d, %s\n", i, 187 PORT_ErrorToString(PORT_GetError())); 188 } 189 } 190 printf("waiting on %d threads\n", THREAD_COUNT); 191 for (i = 0; i < THREAD_COUNT; i++) { 192 if (thread[i] == NULL) { 193 continue; 194 } 195 status = PR_JoinThread(thread[i]); 196 if (status != PR_SUCCESS) { 197 ERROR++; 198 fprintf(stderr, 199 "PR_CreateThread filed iteration %d, %s\n", i, 200 PORT_ErrorToString(PORT_GetError())); 201 } 202 } 203 if (NSS_Shutdown() != SECSuccess) { 204 ERROR++; 205 fprintf(stderr, "NSS_Shutdown failed: %s\n", 206 PORT_ErrorToString(PORT_GetError())); 207 } 208 printf("%d failures and %d errors found\n", FAILED, ERROR); 209 /* clean up */ 210 if (FAILED) { 211 exit(1); 212 } 213 if (ERROR) { 214 exit(2); 215 } 216 exit(0); 217 }