Add a function to detect if we have async or not
authorMatt Caswell <matt@openssl.org>
Mon, 7 Mar 2016 16:55:39 +0000 (16:55 +0000)
committerMatt Caswell <matt@openssl.org>
Mon, 7 Mar 2016 17:23:42 +0000 (17:23 +0000)
Add the ASYNC_is_capable() function and use it in speed.

Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Rich Salz <rsalz@openssl.org>
apps/speed.c
crypto/async/arch/async_null.c
crypto/async/arch/async_posix.c
crypto/async/arch/async_win.c
doc/crypto/ASYNC_start_job.pod
include/openssl/async.h

index f45a3e2106d979003e0427fb6f629b1063be6a6e..4d3a9383f57abdf0259a82ee4a06ef103aad6402 100644 (file)
 # include <windows.h>
 #endif
 
-#if defined(OPENSSL_SYS_UNIX) && defined(OPENSSL_THREADS)
-# include <unistd.h>
-#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 <openssl/bn.h>
 #ifndef OPENSSL_NO_DES
 # include <openssl/des.h>
@@ -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:
index 7b93090a9a87c13bb295a1a776108963a44effa9..f0b8a5c315f0de8f49aa33c4f254d880cfcd454c 100644 (file)
 
 #ifdef ASYNC_NULL
 
+int ASYNC_is_capable(void)
+{
+    return 0;
+}
+
 void async_local_cleanup(void)
 {
 }
index 553ec664e2ce0762bafc8e8304e273829154d556..2d9e5102fcdcbd63f2f246b06caf895eb2d3991a 100644 (file)
 
 #define STACKSIZE       32768
 
-void async_local_cleanup(void)
+int ASYNC_is_capable(void)
 {
+    return 1;
 }
 
+void async_local_cleanup(void)
+{
+}
 
 int async_fibre_makecontext(async_fibre *fibre)
 {
index 6b948c3d9cf394c3b59e8587edb2218299d23547..4f4c799e9863d7ab3a0f7631404df36c3b1fe31d 100644 (file)
 # include <windows.h>
 # include "internal/cryptlib.h"
 
+int ASYNC_is_capable(void)
+{
+    return 1;
+}
+
 void async_local_cleanup(void)
 {
     async_ctx *ctx = async_get_ctx();
index 81fdc97df47ac07aedb1776588ff1b1cd90733c8..c64af3d34078a782f1d3902125c61b68a9aea788 100644 (file)
@@ -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<crypto(3)>, L<ERR_print_errors(3)>
 
 =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
index 4b081b3bbdde5fdc5b064659acea31fd15049ad4..635855f25887f3a35de14eb14b3b84baec7be6ec 100644 (file)
@@ -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);