From patchwork Fri May 20 10:59:37 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v4,3/3] coroutine: add check-coroutine --benchmark-lifecycle Date: Fri, 20 May 2011 00:59:37 -0000 From: Stefan Hajnoczi X-Patchwork-Id: 96581 Message-Id: <1305889177-10490-4-git-send-email-stefanha@linux.vnet.ibm.com> To: Cc: Kevin Wolf , Anthony Liguori , Stefan Hajnoczi , Blue Swirl , Paolo Bonzini , Venkateswararao Jujjuri 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 --- check-coroutine.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/check-coroutine.c b/check-coroutine.c index f65ac2e..8ed1a4f 100644 --- a/check-coroutine.c +++ b/check-coroutine.c @@ -11,8 +11,10 @@ * */ +#include #include #include +#include #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; + long 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 ]\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);