This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Tarantool -- an efficient key/value data store".
The branch fiber-raise has been created
at f5e9d16768f3e5dacb675a0650b27439e18e324b (commit)
commit f5e9d16768f3e5dacb675a0650b27439e18e324b
Author: Yuriy Vostrikov <[email protected]>
Date: Mon Dec 6 14:32:12 2010 +0300
[core] Add ability to raise an exception in the other fiber.
diff --git a/core/fiber.c b/core/fiber.c
index 1e9b741..328e4d0 100644
--- a/core/fiber.c
+++ b/core/fiber.c
@@ -110,6 +110,24 @@ fiber_call(struct fiber *callee)
}
void
+fiber_raise(struct fiber *callee, jmp_buf exc, int value)
+{
+ struct fiber *caller = fiber;
+
+ assert(sp - call_stack < 8);
+ assert(caller);
+
+ fiber = callee;
+ *sp++ = caller;
+
+#if CORO_ASM
+ save_rbp(&caller->rbp);
+#endif
+ callee->csw++;
+ coro_save_and_longjmp(&caller->coro.ctx, exc, value);
+}
+
+void
yield(void)
{
struct fiber *callee = *(--sp);
diff --git a/include/fiber.h b/include/fiber.h
index 63e21ad..7a18070 100644
--- a/include/fiber.h
+++ b/include/fiber.h
@@ -156,6 +156,7 @@ ssize_t fiber_flush_output(void);
void fiber_cleanup(void);
void fiber_gc(void);
void fiber_call(struct fiber *callee);
+void fiber_raise(struct fiber *callee, jmp_buf exc, int value);
int fiber_connect(struct sockaddr_in *addr);
void fiber_sleep(ev_tstamp s);
void fiber_info(struct tbuf *out);
diff --git a/third_party/coro/coro.c b/third_party/coro/coro.c
index 43c8824..3546628 100644
--- a/third_party/coro/coro.c
+++ b/third_party/coro/coro.c
@@ -150,6 +150,40 @@ trampoline (int sig)
#endif
"\tret\n"
);
+ asm (
+ ".text\n"
+ ".globl coro_save_and_longjmp\n"
+ ".type coro_save_and_longjmp, @function\n"
+ "coro_save_and_longjmp:\n"
+ #if __amd64
+ #define NUM_SAVED 6
+ "\tpush %rbp\n"
+ "\tpush %rbx\n"
+ "\tpush %r12\n"
+ "\tpush %r13\n"
+ "\tpush %r14\n"
+ "\tpush %r15\n"
+ "\tmov %rsp, (%rdi)\n"
+ "\tmovq %rsi, %rdi\n"
+ "\tsubq $8, %rsp\n"
+ "\tmovl %edx, %esi\n"
+ "\tcall longjmp\n"
+ #elif __i386
+ #define NUM_SAVED 4
+ "\tpush %ebp\n"
+ "\tpush %ebx\n"
+ "\tpush %esi\n"
+ "\tpush %edi\n"
+ "\tmov %esp, (%eax)\n"
+ "\tsubl $0x28,%esp\n"
+ "\tmovl %ecx,0x4(%esp)\n"
+ "\tmovl %edx,(%esp)\n"
+ "\tcall longjmp\n"
+ #else
+ #error unsupported architecture
+ #endif
+ "\tret\n"
+ );
# endif
diff --git a/third_party/coro/coro.h b/third_party/coro/coro.h
index bc84c0a..e931718 100644
--- a/third_party/coro/coro.h
+++ b/third_party/coro/coro.h
@@ -262,16 +262,21 @@ struct coro_context {
};
# define coro_transfer(p,n) do { if (!coro_setjmp ((p)->env)) coro_longjmp
((n)->env); } while (0)
+# define coro_save_and_longjmp(p,j,v) do { if (!coro_setjmp ((p)->env))
longjmp (j,v); } while (0)
# define coro_destroy(ctx) (void *)(ctx)
#elif CORO_ASM
+# include <setjmp.h> /* for jmp_buf */
+
struct coro_context {
void **sp; /* must be at offset 0 */
};
void __attribute__ ((noinline, regparm(2)))
coro_transfer (coro_context *prev, coro_context *next);
+void __attribute__ ((noinline, regparm(3)))
+coro_save_and_longjmp (coro_context *prev, jmp_buf jump, int value);
# define coro_destroy(ctx) (void *)(ctx)
--
Tarantool -- an efficient key/value data store
_______________________________________________
Mailing list: https://launchpad.net/~tarantool-developers
Post to : [email protected]
Unsubscribe : https://launchpad.net/~tarantool-developers
More help : https://help.launchpad.net/ListHelp