From a58e71c571065330fa647ed0c4fe04f0b10b14d8 Mon Sep 17 00:00:00 2001 From: user Date: Wed, 22 Jun 2016 18:50:39 +0000 Subject: [PATCH] Add test for user mode context switches 90% more efficient than thread switching, nice. --- timectxsw_umode.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++ timetctxsw2.c | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 timectxsw_umode.c diff --git a/timectxsw_umode.c b/timectxsw_umode.c new file mode 100644 index 0000000..889185d --- /dev/null +++ b/timectxsw_umode.c @@ -0,0 +1,59 @@ +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include +#include +#include +#include +#include +#include + +const int iterations = 500000; + +static inline long long unsigned time_ns(struct timespec* const ts) { + if (clock_gettime(CLOCK_REALTIME, ts)) { + exit(1); + } + return ((long long unsigned) ts->tv_sec) * 1000000000LLU + + (long long unsigned) ts->tv_nsec; +} + +ucontext_t main_context, other_context; + +void run_other(void) { + int i; + for(i=0;i= 0); + other_context.uc_stack.ss_sp = other_stack; + other_context.uc_stack.ss_size = sizeof(other_stack); + other_context.uc_link = &main_context; + makecontext(&other_context, run_other, 1, &main_context); + + const long long unsigned start_ns = time_ns(&ts); + for (int i = 0; i < iterations; i++) { + assert(swapcontext(&main_context, &other_context) >= 0); + } + const long long unsigned delta = time_ns(&ts) - start_ns; + + const int nswitches = iterations << 2; + printf("%i user mode context switches in %lluns (%.1fns/ctxsw)\n", + nswitches, delta, (delta / (float) nswitches)); + return 0; +} diff --git a/timetctxsw2.c b/timetctxsw2.c index a5cbc18..7bb3e23 100644 --- a/timetctxsw2.c +++ b/timetctxsw2.c @@ -57,7 +57,7 @@ int main(void) { long long unsigned delta = time_ns(&ts) - start_ns; const int nswitches = iterations << 2; - printf("%i thread context switches in %lluns (%.1fns/ctxsw)\n", + printf("%i thread sched_yield context switches in %lluns (%.1fns/ctxsw)\n", nswitches, delta, (delta / (float) nswitches)); return 0; }