From 667867cced0013c1cfd8d7a9efa43b8f2cebc942 Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Mon, 7 Mar 2016 16:55:39 +0000 Subject: [PATCH] Add a function to detect if we have async or not Add the ASYNC_is_capable() function and use it in speed. Reviewed-by: Richard Levitte Reviewed-by: Rich Salz --- apps/speed.c | 42 ++++++++++++--------------------- crypto/async/arch/async_null.c | 5 ++++ crypto/async/arch/async_posix.c | 6 ++++- crypto/async/arch/async_win.c | 5 ++++ doc/crypto/ASYNC_start_job.pod | 19 +++++++++++---- include/openssl/async.h | 2 ++ 6 files changed, 46 insertions(+), 33 deletions(-) diff --git a/apps/speed.c b/apps/speed.c index f45a3e2106..4d3a9383f5 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -99,24 +99,6 @@ # include #endif -#if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS) -# include -#endif - -#if !defined(OPENSSL_NO_ASYNC) -# if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS) -# if _POSIX_VERSION >= 200112L -# define ASYNC_POSIX -# endif -# elif defined(_WIN32) || defined(__CYGWIN__) -# define ASYNC_WIN -# endif -#endif - -#if !defined(ASYNC_POSIX) && !defined(ASYNC_WIN) -# define ASYNC_NULL -#endif - #include #ifndef OPENSSL_NO_DES # include @@ -458,7 +440,7 @@ OPTIONS speed_options[] = { #ifndef NO_FORK {"multi", OPT_MULTI, 'p', "Run benchmarks in parallel"}, #endif -#ifndef ASYNC_NULL +#ifndef OPENSSL_NO_ASYNC {"async_jobs", OPT_ASYNCJOBS, 'p', "Enable async mode and start pnum jobs"}, #endif #ifndef OPENSSL_NO_ENGINE @@ -1136,7 +1118,7 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ int i = 0; OSSL_ASYNC_FD job_fd = 0; size_t num_job_fds = 0; -#if defined(ASYNC_POSIX) +#if defined(OPENSSL_SYS_UNIX) fd_set waitfdset; OSSL_ASYNC_FD max_fd = 0; #endif @@ -1171,7 +1153,7 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ } } -#if defined(ASYNC_POSIX) +#if defined(OPENSSL_SYS_UNIX) FD_ZERO(&waitfdset); /* Add to the wait set all the fds that are already in the WAIT_CTX @@ -1197,7 +1179,7 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ #endif while (num_inprogress > 0) { -#if defined(ASYNC_POSIX) +#if defined(OPENSSL_SYS_UNIX) int select_result = 0; struct timeval select_timeout; select_timeout.tv_sec = 0; @@ -1252,7 +1234,7 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ if (select_result == 0) continue; -#elif defined(ASYNC_WIN) +#elif defined(OPENSSL_SYS_WINDOWS) DWORD avail = 0; #endif @@ -1269,10 +1251,10 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ } ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds); -#if defined(ASYNC_POSIX) +#if defined(OPENSSL_SYS_UNIX) if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset)) continue; -#elif defined(ASYNC_WIN) +#elif defined(OPENSSL_SYS_WINDOWS) if (num_job_fds == 1 && !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL) && avail > 0) continue; @@ -1290,7 +1272,7 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ total_op_count += job_op_count; } --num_inprogress; -#if defined(ASYNC_POSIX) +#if defined(OPENSSL_SYS_UNIX) FD_CLR(job_fd, &waitfdset); #endif loopargs[i].inprogress_job = NULL; @@ -1520,8 +1502,14 @@ int speed_main(int argc, char **argv) #endif break; case OPT_ASYNCJOBS: -#ifndef ASYNC_NULL +#ifndef OPENSSL_NO_ASYNC async_jobs = atoi(opt_arg()); + if (!ASYNC_is_capable()) { + BIO_printf(bio_err, + "%s: async_jobs specified but async not supported\n", + prog); + goto opterr; + } #endif break; case OPT_MISALIGN: diff --git a/crypto/async/arch/async_null.c b/crypto/async/arch/async_null.c index 7b93090a9a..f0b8a5c315 100644 --- a/crypto/async/arch/async_null.c +++ b/crypto/async/arch/async_null.c @@ -55,6 +55,11 @@ #ifdef ASYNC_NULL +int ASYNC_is_capable(void) +{ + return 0; +} + void async_local_cleanup(void) { } diff --git a/crypto/async/arch/async_posix.c b/crypto/async/arch/async_posix.c index 553ec664e2..2d9e5102fc 100644 --- a/crypto/async/arch/async_posix.c +++ b/crypto/async/arch/async_posix.c @@ -60,11 +60,15 @@ #define STACKSIZE 32768 +int ASYNC_is_capable(void) +{ + return 1; +} + void async_local_cleanup(void) { } - int async_fibre_makecontext(async_fibre *fibre) { fibre->env_init = 0; diff --git a/crypto/async/arch/async_win.c b/crypto/async/arch/async_win.c index 6b948c3d9c..4f4c799e98 100644 --- a/crypto/async/arch/async_win.c +++ b/crypto/async/arch/async_win.c @@ -58,6 +58,11 @@ # include # include "internal/cryptlib.h" +int ASYNC_is_capable(void) +{ + return 1; +} + void async_local_cleanup(void) { async_ctx *ctx = async_get_ctx(); diff --git a/doc/crypto/ASYNC_start_job.pod b/doc/crypto/ASYNC_start_job.pod index 81fdc97df4..c64af3d340 100644 --- a/doc/crypto/ASYNC_start_job.pod +++ b/doc/crypto/ASYNC_start_job.pod @@ -4,8 +4,8 @@ ASYNC_init_thread, ASYNC_cleanup_thread, ASYNC_start_job, ASYNC_pause_job, ASYNC_in_job, ASYNC_get_wait_fd, ASYNC_set_wait_fd, ASYNC_clear_wait_fd, -ASYNC_get_current_job, ASYNC_block_pause, ASYNC_unblock_pause - asynchronous job -management functions +ASYNC_get_current_job, ASYNC_block_pause, ASYNC_unblock_pause, ASYNC_is_capable +- asynchronous job management functions =head1 SYNOPSIS @@ -23,6 +23,8 @@ management functions void ASYNC_block_pause(void); void ASYNC_unblock_pause(void); + int ASYNC_is_capable(void); + =head1 DESCRIPTION OpenSSL implements asynchronous capabilities through an ASYNC_JOB. This @@ -137,6 +139,9 @@ ASYNC_block_pause() immediately after aquiring the lock and ASYNC_unblock_pause() immediately before releasing it then this situation cannot occur. +Some platforms cannot support async operations. The ASYNC_is_capable() function +can be used to detect whether the current platform is async capable or not. + =head1 RETURN VALUES ASYNC_init_thread returns 1 on success or 0 otherwise. @@ -153,6 +158,9 @@ NULL if not within the context of a job. ASYNC_get_wait_ctx() returns a pointer to the ASYNC_WAIT_CTX for the job. +ASYNC_is_capable() returns 1 if the current platform is async capable or 0 +otherwise. + =head1 EXAMPLE The following example demonstrates how to use most of the core async APIs: @@ -295,8 +303,9 @@ L, L =head1 HISTORY -ASYNC_init, ASYNC_init_thread, ASYNC_cleanup, ASYNC_cleanup_thread, -ASYNC_start_job, ASYNC_pause_job, ASYNC_get_wait_fd, ASYNC_get_current_job, -ASYNC_wake, ASYNC_clear_wake were first added to OpenSSL 1.1.0. +ASYNC_init_thread, ASYNC_cleanup_thread, +ASYNC_start_job, ASYNC_pause_job, ASYNC_get_current_job, ASYNC_get_wait_ctx(), +ASYNC_block_pause(), ASYNC_unblock_pause() and ASYNC_is_capable() were first +added to OpenSSL 1.1.0. =cut diff --git a/include/openssl/async.h b/include/openssl/async.h index 4b081b3bbd..635855f258 100644 --- a/include/openssl/async.h +++ b/include/openssl/async.h @@ -96,6 +96,8 @@ int ASYNC_WAIT_CTX_get_changed_fds(ASYNC_WAIT_CTX *ctx, OSSL_ASYNC_FD *addfd, size_t *numdelfds); int ASYNC_WAIT_CTX_clear_fd(ASYNC_WAIT_CTX *ctx, const void *key); +int ASYNC_is_capable(void); + int ASYNC_start_job(ASYNC_JOB **job, ASYNC_WAIT_CTX *ctx, int *ret, int (*func)(void *), void *args, size_t size); int ASYNC_pause_job(void);