[Spice-devel] [PATCH 1/5] use _setjmp/_longjmp to speed up coroutine switching

Marc-André Lureau marcandre.lureau at gmail.com
Wed Aug 17 05:45:11 PDT 2011


As described in http://www.1024cores.net/home/lock-free-algorithms/tricks/fibers
---
 gtk/continuation.c |   12 +++++++++++-
 gtk/continuation.h |    2 ++
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/gtk/continuation.c b/gtk/continuation.c
index 4f5b027..6eaed3c 100644
--- a/gtk/continuation.c
+++ b/gtk/continuation.c
@@ -21,6 +21,7 @@
 #include <config.h>
 
 #include "continuation.h"
+#undef _FORTIFY_SOURCE
 
 /*
  * va_args to makecontext() must be type 'int', so passing
@@ -40,6 +41,11 @@ static void continuation_trampoline(int i0, int i1)
 	arg.i[1] = i1;
 	cc = arg.p;
 
+	if (_setjmp(cc->jmp) == 0) {
+		ucontext_t tmp;
+		swapcontext(&tmp, &cc->last);
+	}
+
 	cc->entry(cc);
 }
 
@@ -56,6 +62,7 @@ int cc_init(struct continuation *cc)
 	cc->uc.uc_stack.ss_flags = 0;
 
 	makecontext(&cc->uc, (void *)continuation_trampoline, 2, arg.i[0], arg.i[1]);
+	swapcontext(&cc->last, &cc->uc);
 
 	return 0;
 }
@@ -78,7 +85,10 @@ int cc_swap(struct continuation *from, struct continuation *to)
 	else if (to->exited == 1)
 		return 1;
 
-	return swapcontext(&from->uc, &to->uc);
+	if (_setjmp(from->jmp) == 0)
+		_longjmp(to->jmp, 1);
+
+	return 0;
 }
 /*
  * Local variables:
diff --git a/gtk/continuation.h b/gtk/continuation.h
index 87cd4ee..1247337 100644
--- a/gtk/continuation.h
+++ b/gtk/continuation.h
@@ -23,6 +23,7 @@
 
 #include <stddef.h>
 #include <ucontext.h>
+#include <setjmp.h>
 
 struct continuation
 {
@@ -35,6 +36,7 @@ struct continuation
 	ucontext_t uc;
 	ucontext_t last;
 	int exited;
+	jmp_buf jmp;
 };
 
 int cc_init(struct continuation *cc);
-- 
1.7.6



More information about the Spice-devel mailing list