2929
3030#define RUN_TIME 5
3131#define NONCE_CFG "file:servercert.pem"
32+ #define CTX_SHARE_THREADS 1
3233
3334static size_t timeout_us = RUN_TIME * 1000000 ;
3435
@@ -53,6 +54,10 @@ struct nonce_cfg {
5354 size_t num_dirs ;
5455};
5556
57+ struct thread_data {
58+ X509_STORE_CTX * ctx ;
59+ } * thread_data ;
60+
5661static int error = 0 ;
5762static int verbosity = VERBOSITY_DEFAULT ;
5863static X509_STORE * store = NULL ;
@@ -148,20 +153,15 @@ make_nonce(struct nonce_cfg *cfg)
148153static void
149154do_x509storeissuer (size_t num )
150155{
156+ struct thread_data * td = thread_data + num ;
151157 X509_STORE_CTX * ctx = X509_STORE_CTX_new ();
152158 X509 * issuer = NULL ;
153159 OSSL_TIME time = ossl_time_now ();
154160 size_t count = 0 ;
155161 size_t found = 0 ;
156162
157- if (ctx == NULL || !X509_STORE_CTX_init (ctx , store , x509_nonce , NULL )) {
158- warnx ("Failed to initialise X509_STORE_CTX" );
159- error = 1 ;
160- goto err ;
161- }
162-
163163 do {
164- if (X509_STORE_CTX_get1_issuer (& issuer , ctx , x509_nonce ) != 0 ) {
164+ if (X509_STORE_CTX_get1_issuer (& issuer , td -> ctx , x509_nonce ) != 0 ) {
165165 found ++ ;
166166 X509_free (issuer );
167167 }
@@ -183,7 +183,7 @@ usage(char * const argv[])
183183{
184184 fprintf (stderr ,
185185 "Usage: %s [-t] [-v] [-T time] [-n nonce_type:type_args] "
186- "certsdir [certsdir...] threadcount\n"
186+ "[-C threads] certsdir [certsdir...] threadcount\n"
187187 "\t-t\tTerse output\n"
188188 "\t-v\tVerbose output. Multiple usage increases verbosity.\n"
189189 "\t-T\tTimeout for the test run in seconds,\n"
@@ -193,6 +193,9 @@ usage(char * const argv[])
193193 "\t\t\tfile:PATH - load nonce certificate from PATH;\n"
194194 "\t\t\tif PATH is relative, the provided certsdir's are searched.\n"
195195 "\t\tDefault: " NONCE_CFG "\n"
196+ "\t-C\tNumber of threads that share the same X.509\n"
197+ "\t\tstore context object. Default: "
198+ OPENSSL_MSTR (CTX_SHARE_THREADS ) "\n"
196199 , basename (argv [0 ]));
197200}
198201
@@ -254,6 +257,7 @@ main(int argc, char *argv[])
254257{
255258 int i ;
256259 OSSL_TIME duration ;
260+ size_t ctx_share_cnt = CTX_SHARE_THREADS ;
257261 size_t total_count = 0 ;
258262 size_t total_found = 0 ;
259263 double avcalltime ;
@@ -265,7 +269,7 @@ main(int argc, char *argv[])
265269
266270 parse_nonce_cfg (NONCE_CFG , & nonce_cfg );
267271
268- while ((opt = getopt (argc , argv , "tvT:n:" )) != -1 ) {
272+ while ((opt = getopt (argc , argv , "tvT:n:C: " )) != -1 ) {
269273 switch (opt ) {
270274 case 't' : /* terse */
271275 verbosity = VERBOSITY_TERSE ;
@@ -284,6 +288,10 @@ main(int argc, char *argv[])
284288 case 'n' : /* nonce */
285289 parse_nonce_cfg (optarg , & nonce_cfg );
286290 break ;
291+ case 'C' : /* how many threads share X509_STORE_CTX */
292+ ctx_share_cnt = parse_int (optarg , 1 , INT_MAX ,
293+ "X509_STORE_CTX share degree" );
294+ break ;
287295 default :
288296 usage (argv );
289297 return EXIT_FAILURE ;
@@ -307,6 +315,10 @@ main(int argc, char *argv[])
307315
308316 threadcount = parse_int (argv [argc - 1 ], 1 , INT_MAX , "threadcount" );
309317
318+ thread_data = OPENSSL_zalloc (threadcount * sizeof (* thread_data ));
319+ if (thread_data == NULL )
320+ errx (EXIT_FAILURE , "Failed to create thread_data array" );
321+
310322 store = X509_STORE_new ();
311323 if (store == NULL || !X509_STORE_set_default_paths (store ))
312324 errx (EXIT_FAILURE , "Failed to create X509_STORE" );
@@ -402,6 +414,19 @@ main(int argc, char *argv[])
402414 if (x509_nonce == NULL )
403415 errx (EXIT_FAILURE , "Unable to create the nonce X509 object" );
404416
417+ for (size_t i = 0 ; i < threadcount ; i ++ ) {
418+ if (i % ctx_share_cnt ) {
419+ thread_data [i ].ctx = thread_data [i - i % ctx_share_cnt ].ctx ;
420+ } else {
421+ thread_data [i ].ctx = X509_STORE_CTX_new ();
422+ if (thread_data [i ].ctx == NULL
423+ || !X509_STORE_CTX_init (thread_data [i ].ctx , store , x509_nonce ,
424+ NULL ))
425+ errx (EXIT_FAILURE , "Failed to initialise X509_STORE_CTX"
426+ " for thread %zu" , i );
427+ }
428+ }
429+
405430 max_time = ossl_time_add (ossl_time_now (), ossl_us2time (timeout_us ));
406431
407432 if (!perflib_run_multi_thread_test (do_x509storeissuer , threadcount , & duration ))
@@ -439,5 +464,10 @@ main(int argc, char *argv[])
439464 X509_STORE_free (store );
440465 OPENSSL_free (founds );
441466 OPENSSL_free (counts );
467+ if (thread_data != NULL ) {
468+ for (size_t i = 0 ; i < threadcount ; i += ctx_share_cnt )
469+ X509_STORE_CTX_free (thread_data [i ].ctx );
470+ }
471+ OPENSSL_free (thread_data );
442472 return ret ;
443473}
0 commit comments