summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimo Teras <timo.teras@iki.fi>2009-12-01 13:55:43 +0200
committerTimo Teras <timo.teras@iki.fi>2009-12-01 13:55:43 +0200
commitffe17e686d99efc672b31e6876dcc4e30a05a572 (patch)
tree8facc066e3cf4da3fe0b2ab2ab4dc015318afc61
parent959645020619f02d6ab8bb4026b0e0121b3971da (diff)
downloadlibtf-ffe17e686d99efc672b31e6876dcc4e30a05a572.tar.bz2
libtf-ffe17e686d99efc672b31e6876dcc4e30a05a572.tar.xz
libtf: optimize x86 fiber switching
by letting gcc figure out better how to represent stack pointers. also uses labels to make the code more readable.
-rw-r--r--src/fiber.c2
-rw-r--r--src/uctx.h39
2 files changed, 25 insertions, 16 deletions
diff --git a/src/fiber.c b/src/fiber.c
index 6ddde1b..a7cb6bd 100644
--- a/src/fiber.c
+++ b/src/fiber.c
@@ -225,7 +225,7 @@ int tf_schedule(void)
if (unlikely(f->timeout_change)) {
if (f->timeout_change & TF_TIMEOUT_CHANGE_NEW_VALUE) {
if (tf_mtime_diff(f->timeout, tf_mtime()) <= 0) {
- f->timeout_change = TF_TIMEOUT_CHANGE;
+ f->timeout_change = TF_TIMEOUT_CHANGE_NEEDED;
return TF_WAKEUP_TIMEOUT;
}
tf_heap_change(&f->heap_node, &sched->heap, f->timeout);
diff --git a/src/uctx.h b/src/uctx.h
index 03750e9..541fcf9 100644
--- a/src/uctx.h
+++ b/src/uctx.h
@@ -32,10 +32,32 @@ struct tf_uctx {
#if defined(__i386__)
+#define switch_fiber(prev, next) \
+ do { \
+ unsigned eax, ebx, ecx, edx, esi, edi; \
+ __asm__ __volatile__ ( \
+ "push %%ebp \n" \
+ "call 1f \n" \
+ "1: \n" \
+ "addl $2f-1b, (%%esp) \n" \
+ "movl %%esp, %[prev_sp] \n" \
+ "movl %[next_sp], %%esp \n" \
+ "ret \n" \
+ "2: \n" \
+ "pop %%ebp \n" \
+ : [prev_sp] "=m"(prev->current_sp), \
+ "=a"(eax), "=b"(ebx), "=c"(ecx), \
+ "=d"(edx), "=S"(esi), "=D"(edi) \
+ : [next_sp] "m"(next->current_sp) \
+ : "memory", "cc"); \
+ } while (0)
+
#define STACK_GROWS_UP
#else
-#error Your architecture is not supported. Send email to timo.teras@iki.fi.
+
+#error Your architecture is not supported. Contact timo.teras@iki.fi.
+
#endif
#if defined(STACK_GROWS_UP)
@@ -108,19 +130,6 @@ void tf_uctx_destroy(struct tf_fiber *fiber)
free(uctx->alloc);
}
-#define switch_fiber(oldspptr, newsp) \
- __asm__ __volatile__ ( \
- "push %%ebp ;" \
- "call .+5 ;" \
- "add $0x9,(%%esp) ;" \
- "mov %%esp, (%0) ;" \
- "mov %1, %%esp ;" \
- "ret ;" \
- "pop %%ebp" \
- : \
- : "a"(oldspptr), "d"(newsp) \
- : "%ebx", "%ecx", "%esi", "%edi", "memory", "cc");
-
static inline
void tf_uctx_transfer(struct tf_fiber *from, struct tf_fiber *to)
{
@@ -130,5 +139,5 @@ void tf_uctx_transfer(struct tf_fiber *from, struct tf_fiber *to)
/* Switch stack pointers */
TF_BUG_ON(*ufrom->stack_guard != STACK_GUARD);
- switch_fiber(&ufrom->current_sp, uto->current_sp);
+ switch_fiber(ufrom, uto);
}