From 1e61392296d15b1edb89e346e1f75d0235aba2e7 Mon Sep 17 00:00:00 2001 From: Andrea Grandi Date: Mon, 29 Feb 2016 11:28:55 +0000 Subject: [PATCH] Add support to ASYNC_WAIT_CTX to speed Reviewed-by: Richard Levitte Reviewed-by: Matt Caswell --- apps/speed.c | 115 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 97 insertions(+), 18 deletions(-) diff --git a/apps/speed.c b/apps/speed.c index 32b4d05e70..f45a3e2106 100644 --- a/apps/speed.c +++ b/apps/speed.c @@ -217,6 +217,7 @@ static int usertime = 1; typedef struct loopargs_st { ASYNC_JOB *inprogress_job; + ASYNC_WAIT_CTX *wait_ctx; unsigned char *buf; unsigned char *buf2; unsigned char *buf_malloc; @@ -1133,6 +1134,12 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ int num_inprogress = 0; int error = 0; int i = 0; + OSSL_ASYNC_FD job_fd = 0; + size_t num_job_fds = 0; +#if defined(ASYNC_POSIX) + fd_set waitfdset; + OSSL_ASYNC_FD max_fd = 0; +#endif run = 1; @@ -1140,9 +1147,11 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ return loop_function((void *)loopargs); } + for (i = 0; i < async_jobs && !error; i++) { - switch (ASYNC_start_job(&(loopargs[i].inprogress_job), &job_op_count, - loop_function, (void *)(loopargs + i), sizeof(loopargs_t))) { + switch (ASYNC_start_job(&(loopargs[i].inprogress_job), loopargs[i].wait_ctx, + &job_op_count, loop_function, + (void *)(loopargs + i), sizeof(loopargs_t))) { case ASYNC_PAUSE: ++num_inprogress; break; @@ -1162,23 +1171,70 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ } } +#if defined(ASYNC_POSIX) + FD_ZERO(&waitfdset); + + /* Add to the wait set all the fds that are already in the WAIT_CTX + * This is required when the same ctx is used multiple times + * For the purpose of speed, each job can be associated to at most one fd + */ + for (i = 0; i < async_jobs && num_inprogress > 0; i++) { + if (loopargs[i].inprogress_job == NULL) + continue; + + if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds) + || num_job_fds > 1) { + BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n"); + ERR_print_errors(bio_err); + error = 1; + break; + } + ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds); + FD_SET(job_fd, &waitfdset); + if (job_fd > max_fd) + max_fd = job_fd; + } +#endif + while (num_inprogress > 0) { - OSSL_ASYNC_FD job_fd = 0; #if defined(ASYNC_POSIX) - OSSL_ASYNC_FD max_fd = 0; int select_result = 0; - fd_set waitfdset; struct timeval select_timeout; - FD_ZERO(&waitfdset); - select_timeout.tv_sec=0; - select_timeout.tv_usec=0; + select_timeout.tv_sec = 0; + select_timeout.tv_usec = 0; for (i = 0; i < async_jobs; i++) { if (loopargs[i].inprogress_job != NULL) { - job_fd = ASYNC_get_wait_fd(loopargs[i].inprogress_job); - FD_SET(job_fd, &waitfdset); - if (job_fd > max_fd) - max_fd = job_fd; + /* Consider only changed fds to minimize the operations on waitfdset */ + OSSL_ASYNC_FD add_fd, del_fd; + size_t num_add_fds, num_del_fds; + if (!ASYNC_WAIT_CTX_get_changed_fds(loopargs[i].wait_ctx, NULL, + &num_add_fds, NULL, &num_del_fds)) { + BIO_printf(bio_err, "Failure in ASYNC_WAIT_CTX\n"); + ERR_print_errors(bio_err); + error = 1; + break; + } + if (num_add_fds > 1 || num_del_fds > 1) { + BIO_printf(bio_err, "Too many fds have changed in ASYNC_WAIT_CTX\n"); + ERR_print_errors(bio_err); + error = 1; + break; + } + if (num_add_fds == 0 && num_del_fds == 0) + continue; + + ASYNC_WAIT_CTX_get_changed_fds(loopargs[i].wait_ctx, &add_fd, &num_add_fds, + &del_fd, &num_del_fds); + + if (num_del_fds == 1) + FD_CLR(del_fd, &waitfdset); + + if (num_add_fds == 1) { + FD_SET(add_fd, &waitfdset); + if (add_fd > max_fd) + max_fd = add_fd; + } } } select_result = select(max_fd + 1, &waitfdset, NULL, NULL, &select_timeout); @@ -1204,17 +1260,25 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ if (loopargs[i].inprogress_job == NULL) continue; - job_fd = ASYNC_get_wait_fd(loopargs[i].inprogress_job); + if (!ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, NULL, &num_job_fds) + || num_job_fds > 1) { + BIO_printf(bio_err, "Too many fds in ASYNC_WAIT_CTX\n"); + ERR_print_errors(bio_err); + error = 1; + break; + } + ASYNC_WAIT_CTX_get_all_fds(loopargs[i].wait_ctx, &job_fd, &num_job_fds); #if defined(ASYNC_POSIX) - if (!FD_ISSET(job_fd, &waitfdset)) + if (num_job_fds == 1 && !FD_ISSET(job_fd, &waitfdset)) continue; #elif defined(ASYNC_WIN) - if (!PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL) && avail > 0) + if (num_job_fds == 1 && + !PeekNamedPipe(job_fd, NULL, 0, NULL, &avail, NULL) && avail > 0) continue; #endif - switch (ASYNC_start_job(&(loopargs[i].inprogress_job), + switch (ASYNC_start_job(&(loopargs[i].inprogress_job), loopargs[i].wait_ctx, &job_op_count, loop_function, (void *)(loopargs + i), sizeof(loopargs_t))) { case ASYNC_PAUSE: @@ -1226,6 +1290,9 @@ static int run_benchmark(int async_jobs, int (*loop_function)(void *), loopargs_ total_op_count += job_op_count; } --num_inprogress; +#if defined(ASYNC_POSIX) + FD_CLR(job_fd, &waitfdset); +#endif loopargs[i].inprogress_job = NULL; break; case ASYNC_NO_JOBS: @@ -1574,6 +1641,14 @@ int speed_main(int argc, char **argv) memset(loopargs, 0, loopargs_len * sizeof(loopargs_t)); for (i = 0; i < loopargs_len; i++) { + if (async_jobs > 0) { + loopargs[i].wait_ctx = ASYNC_WAIT_CTX_new(); + if (loopargs[i].wait_ctx == NULL) { + BIO_printf(bio_err, "Error creating the ASYNC_WAIT_CTX\n"); + goto end; + } + } + loopargs[i].buf_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer"); loopargs[i].buf2_malloc = app_malloc((int)BUFSIZE + MAX_MISALIGNMENT + 1, "input buffer"); /* Align the start of buffers on a 64 byte boundary */ @@ -2820,7 +2895,6 @@ int speed_main(int argc, char **argv) OPENSSL_free(loopargs[i].buf2_malloc); OPENSSL_free(loopargs[i].siglen); } - OPENSSL_free(loopargs); #ifndef OPENSSL_NO_RSA for (i = 0; i < loopargs_len; i++) { for (k = 0; k < RSA_NUM; k++) @@ -2845,8 +2919,13 @@ int speed_main(int argc, char **argv) OPENSSL_free(loopargs[i].secret_b); } #endif - if (async_jobs > 0) + if (async_jobs > 0) { + for (i = 0; i < loopargs_len; i++) + ASYNC_WAIT_CTX_free(loopargs[i].wait_ctx); + ASYNC_cleanup_thread(); + } + OPENSSL_free(loopargs); return (ret); } -- 2.34.1