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 ;
@@ -290,20 +295,15 @@ read_certsdirs(char * const * const dirs, const int dir_cnt,
290295static void
291296do_x509storeissuer (size_t num )
292297{
298+ struct thread_data * td = thread_data + num ;
293299 X509_STORE_CTX * ctx = X509_STORE_CTX_new ();
294300 X509 * issuer = NULL ;
295301 OSSL_TIME time = ossl_time_now ();
296302 size_t count = 0 ;
297303 size_t found = 0 ;
298304
299- if (ctx == NULL || !X509_STORE_CTX_init (ctx , store , x509_nonce , NULL )) {
300- warnx ("Failed to initialise X509_STORE_CTX" );
301- error = 1 ;
302- goto err ;
303- }
304-
305305 do {
306- if (X509_STORE_CTX_get1_issuer (& issuer , ctx , x509_nonce ) != 0 ) {
306+ if (X509_STORE_CTX_get1_issuer (& issuer , td -> ctx , x509_nonce ) != 0 ) {
307307 found ++ ;
308308 X509_free (issuer );
309309 }
@@ -325,7 +325,7 @@ usage(char * const argv[])
325325{
326326 fprintf (stderr ,
327327 "Usage: %s [-t] [-v] [-T time] [-n nonce_type:type_args] "
328- "certsdir [certsdir...] threadcount\n"
328+ "[-C threads] certsdir [certsdir...] threadcount\n"
329329 "\t-t\tTerse output\n"
330330 "\t-v\tVerbose output. Multiple usage increases verbosity.\n"
331331 "\t-T\tTimeout for the test run in seconds,\n"
@@ -335,6 +335,9 @@ usage(char * const argv[])
335335 "\t\t\tfile:PATH - load nonce certificate from PATH;\n"
336336 "\t\t\tif PATH is relative, the provided certsdir's are searched.\n"
337337 "\t\tDefault: " NONCE_CFG "\n"
338+ "\t-C\tNumber of threads that share the same X.509\n"
339+ "\t\tstore context object. Default: "
340+ OPENSSL_MSTR (CTX_SHARE_THREADS ) "\n"
338341 , basename (argv [0 ]));
339342}
340343
@@ -396,6 +399,7 @@ main(int argc, char *argv[])
396399{
397400 int i ;
398401 OSSL_TIME duration ;
402+ size_t ctx_share_cnt = CTX_SHARE_THREADS ;
399403 size_t total_count = 0 ;
400404 size_t total_found = 0 ;
401405 double avcalltime ;
@@ -407,7 +411,7 @@ main(int argc, char *argv[])
407411
408412 parse_nonce_cfg (NONCE_CFG , & nonce_cfg );
409413
410- while ((opt = getopt (argc , argv , "tvT:n:" )) != -1 ) {
414+ while ((opt = getopt (argc , argv , "tvT:n:C: " )) != -1 ) {
411415 switch (opt ) {
412416 case 't' : /* terse */
413417 verbosity = VERBOSITY_TERSE ;
@@ -426,6 +430,10 @@ main(int argc, char *argv[])
426430 case 'n' : /* nonce */
427431 parse_nonce_cfg (optarg , & nonce_cfg );
428432 break ;
433+ case 'C' : /* how many threads share X509_STORE_CTX */
434+ ctx_share_cnt = parse_int (optarg , 1 , INT_MAX ,
435+ "X509_STORE_CTX share degree" );
436+ break ;
429437 default :
430438 usage (argv );
431439 return EXIT_FAILURE ;
@@ -449,6 +457,10 @@ main(int argc, char *argv[])
449457
450458 threadcount = parse_int (argv [argc - 1 ], 1 , INT_MAX , "threadcount" );
451459
460+ thread_data = OPENSSL_zalloc (threadcount * sizeof (* thread_data ));
461+ if (thread_data == NULL )
462+ errx (EXIT_FAILURE , "Failed to create thread_data array" );
463+
452464 store = X509_STORE_new ();
453465 if (store == NULL || !X509_STORE_set_default_paths (store ))
454466 errx (EXIT_FAILURE , "Failed to create X509_STORE" );
@@ -471,6 +483,19 @@ main(int argc, char *argv[])
471483 if (x509_nonce == NULL )
472484 errx (EXIT_FAILURE , "Unable to create the nonce X509 object" );
473485
486+ for (size_t i = 0 ; i < threadcount ; i ++ ) {
487+ if (i % ctx_share_cnt ) {
488+ thread_data [i ].ctx = thread_data [i - i % ctx_share_cnt ].ctx ;
489+ } else {
490+ thread_data [i ].ctx = X509_STORE_CTX_new ();
491+ if (thread_data [i ].ctx == NULL
492+ || !X509_STORE_CTX_init (thread_data [i ].ctx , store , x509_nonce ,
493+ NULL ))
494+ errx (EXIT_FAILURE , "Failed to initialise X509_STORE_CTX"
495+ " for thread %zu" , i );
496+ }
497+ }
498+
474499 max_time = ossl_time_add (ossl_time_now (), ossl_us2time (timeout_us ));
475500
476501 if (!perflib_run_multi_thread_test (do_x509storeissuer , threadcount , & duration ))
@@ -508,5 +533,10 @@ main(int argc, char *argv[])
508533 X509_STORE_free (store );
509534 OPENSSL_free (founds );
510535 OPENSSL_free (counts );
536+ if (thread_data != NULL ) {
537+ for (size_t i = 0 ; i < threadcount ; i += ctx_share_cnt )
538+ X509_STORE_CTX_free (thread_data [i ].ctx );
539+ }
540+ OPENSSL_free (thread_data );
511541 return ret ;
512542}
0 commit comments