diff --git a/tests/benchmarks/bench_sftp.c b/tests/benchmarks/bench_sftp.c index 5548c1c0..64ad5efc 100644 --- a/tests/benchmarks/bench_sftp.c +++ b/tests/benchmarks/bench_sftp.c @@ -388,3 +388,131 @@ error: sftp_free(sftp); return -1; } + +int benchmarks_async_sftp_aio_up(ssh_session session, + struct argument_s *args, + float *bps) +{ + sftp_session sftp = NULL; + sftp_file file = NULL; + sftp_aio aio = NULL; + struct ssh_list *aio_queue = NULL; + + int concurrent_uploads = args->concurrent_requests; + struct timestamp_struct ts = {0}; + float ms = 0.0f; + + size_t total_bytes = args->datasize * 1024 * 1024; + size_t bytes_requested = 0; + size_t to_write; + ssize_t bytes_written; + int i, rc; + + sftp = sftp_new(session); + if (sftp == NULL) { + return -1; + } + + rc = sftp_init(sftp); + if (rc == SSH_ERROR) { + goto error; + } + + file = sftp_open(sftp, SFTPDIR SFTPFILE, + O_RDWR | O_CREAT | O_TRUNC, 0777); + if (file == NULL) { + goto error; + } + + aio_queue = ssh_list_new(); + if (aio_queue == NULL) { + goto error; + } + + if (args->verbose > 0) { + fprintf(stdout, + "Starting upload of %zu bytes now, " + "using %d concurrent uploads.\n", + total_bytes, concurrent_uploads); + } + + timestamp_init(&ts); + + for (i = 0; + i < concurrent_uploads && bytes_requested < total_bytes; + ++i) { + to_write = total_bytes - bytes_requested; + if (to_write > args->chunksize) { + to_write = args->chunksize; + } + + rc = sftp_aio_begin_write(file, buffer, to_write, &aio); + if (rc == SSH_ERROR) { + goto error; + } + + bytes_requested += to_write; + + /* enqueue */ + rc = ssh_list_append(aio_queue, aio); + if (rc == SSH_ERROR) { + sftp_aio_free(aio); + goto error; + } + } + + while ((aio = ssh_list_pop_head(sftp_aio, aio_queue)) != NULL) { + bytes_written = sftp_aio_wait_write(&aio); + if (bytes_written == SSH_ERROR) { + goto error; + } + + if (bytes_requested == total_bytes) { + /* No need to issue more requests */ + continue; + } + + /* else issue a request */ + to_write = total_bytes - bytes_requested; + if (to_write > args->chunksize) { + to_write = args->chunksize; + } + + rc = sftp_aio_begin_write(file, buffer, to_write, &aio); + if (rc == SSH_ERROR) { + goto error; + } + + bytes_requested += to_write; + + /* enqueue */ + rc = ssh_list_append(aio_queue, aio); + if (rc == SSH_ERROR) { + sftp_aio_free(aio); + goto error; + } + } + + ssh_list_free(aio_queue); + sftp_close(file); + ms = elapsed_time(&ts); + *bps = (float)(8000 * total_bytes) / ms; + if (args->verbose > 0) { + fprintf(stdout, "Upload took %f ms for %zu bytes at %f bps.\n", + ms, total_bytes, *bps); + } + + sftp_free(sftp); + return 0; + +error: + /* Release aio structures corresponding to outstanding requests */ + while ((aio = ssh_list_pop_head(sftp_aio, aio_queue)) != NULL) { + sftp_aio_free(aio); + } + + ssh_list_free(aio_queue); + sftp_close(file); + sftp_free(sftp); + return -1; +} diff --git a/tests/benchmarks/benchmarks.c b/tests/benchmarks/benchmarks.c index 56dc7dce..4229d5a5 100644 --- a/tests/benchmarks/benchmarks.c +++ b/tests/benchmarks/benchmarks.c @@ -70,6 +70,11 @@ struct benchmark benchmarks[] = { .name = "benchmark_async_sftp_aio_download", .fct = benchmarks_async_sftp_aio_down, .enabled = 0 + }, + { + .name = "benchmark_async_sftp_aio_upload", + .fct = benchmarks_async_sftp_aio_up, + .enabled = 0 } #endif /* WITH_SFTP */ }; @@ -160,6 +165,14 @@ static struct argp_option options[] = { .doc = "Download data using asynchronous SFTP AIO api (fast)", .group = 0 }, + { + .name = "async-sftp-aio-upload", + .key = '9', + .arg = NULL, + .flags = 0, + .doc = "Upload data using asynchronous SFTP AIO api (fast)", + .group = 0 + }, { .name = "host", .key = 'h', @@ -224,6 +237,7 @@ static error_t parse_opt (int key, char *arg, struct argp_state *state) case '6': case '7': case '8': + case '9': benchmarks[key - '1'].enabled = 1; arguments->ntests++; break; diff --git a/tests/benchmarks/benchmarks.h b/tests/benchmarks/benchmarks.h index 073e2834..5f54a950 100644 --- a/tests/benchmarks/benchmarks.h +++ b/tests/benchmarks/benchmarks.h @@ -38,6 +38,7 @@ enum libssh_benchmarks { BENCHMARK_SYNC_SFTP_DOWNLOAD, BENCHMARK_ASYNC_SFTP_DOWNLOAD, BENCHMARK_ASYNC_SFTP_AIO_DOWNLOAD, + BENCHMARK_ASYNC_SFTP_AIO_UPLOAD, BENCHMARK_NUMBER }; @@ -99,4 +100,6 @@ int benchmarks_async_sftp_down (ssh_session session, struct argument_s *args, float *bps); int benchmarks_async_sftp_aio_down(ssh_session session, struct argument_s *args, float *bps); +int benchmarks_async_sftp_aio_up(ssh_session session, struct argument_s *args, + float *bps); #endif /* BENCHMARKS_H_ */