diff options
author | Timo Teras <timo.teras@iki.fi> | 2009-12-01 13:55:43 +0200 |
---|---|---|
committer | Timo Teras <timo.teras@iki.fi> | 2009-12-01 13:55:43 +0200 |
commit | ffe17e686d99efc672b31e6876dcc4e30a05a572 (patch) | |
tree | 8facc066e3cf4da3fe0b2ab2ab4dc015318afc61 | |
parent | 959645020619f02d6ab8bb4026b0e0121b3971da (diff) | |
download | libtf-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.c | 2 | ||||
-rw-r--r-- | src/uctx.h | 39 |
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); @@ -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); } |