Add a microbenchmark for coroutine create, enter, and return (aka lifecycle). This is a useful benchmark because users are expected to create many coroutines, one per I/O request for example, and we therefore need to provide good performance in that scenario.
To run: make check-coroutine ./check-coroutine --benchmark-lifecycle 20000000 This will do 20,000,000 coroutine create, enter, return iterations and print the resulting time. Signed-off-by: Stefan Hajnoczi <stefa...@linux.vnet.ibm.com> --- check-coroutine.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/check-coroutine.c b/check-coroutine.c index f65ac2e..5a42c49 100644 --- a/check-coroutine.c +++ b/check-coroutine.c @@ -11,8 +11,10 @@ * */ +#include <string.h> #include <stdlib.h> #include <stdio.h> +#include <sys/time.h> #include "qemu-coroutine.h" static const char *cur_test_name; @@ -163,6 +165,43 @@ static void test_lifecycle(void) test_assert(done, "expected done to be true (second time)"); } +/* + * Lifecycle benchmark + */ + +static void coroutine_fn empty_coroutine(void *opaque) +{ + /* Do nothing */ +} + +static void benchmark_lifecycle(const char *iterations) +{ + Coroutine *coroutine; + unsigned int i, max; + struct timeval start, finish; + time_t dsec; + suseconds_t dusec; + + max = atoi(iterations); + + gettimeofday(&start, NULL); + for (i = 0; i < max; i++) { + coroutine = qemu_coroutine_create(empty_coroutine); + qemu_coroutine_enter(coroutine, NULL); + } + gettimeofday(&finish, NULL); + + dsec = finish.tv_sec - start.tv_sec; + if (finish.tv_usec < start.tv_usec) { + dsec--; + dusec = finish.tv_usec + 1000000 - start.tv_usec; + } else { + dusec = finish.tv_usec - start.tv_usec; + } + printf("Lifecycle %u iterations: %lu sec %lu us\n", + max, dsec, dusec); +} + #define TESTCASE(fn) { #fn, fn } int main(int argc, char **argv) { @@ -179,6 +218,15 @@ int main(int argc, char **argv) }; int i; + if (argc == 3 && strcmp(argv[1], "--benchmark-lifecycle") == 0) { + benchmark_lifecycle(argv[2]); + return EXIT_SUCCESS; + } else if (argc != 1) { + fprintf(stderr, "usage: %s [--benchmark-lifecycle <iterations>]\n", + argv[0]); + return EXIT_FAILURE; + } + for (i = 0; testcases[i].name; i++) { cur_test_name = testcases[i].name; printf("%s\n", testcases[i].name); -- 1.7.4.4