From 283d85ff0a0b7248c125a87c83aff889c7061a25 Mon Sep 17 00:00:00 2001
From: root <root>
Date: Tue, 24 Jul 2001 19:52:55 +0000
Subject: *** empty log message ***

---
 coro.c | 28 +++++++++++++++++++++++-----
 coro.h | 15 +++++++++++----
 2 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/coro.c b/coro.c
index bc34ea7..77f628b 100644
--- a/coro.c
+++ b/coro.c
@@ -32,7 +32,7 @@
 
 #include "coro.h"
 
-#if CORO_LOOSE || CORO_SJLJ
+#if CORO_LOOSE || CORO_SJLJ || CORO_LINUX
 
 #include <signal.h>
 
@@ -91,7 +91,7 @@ void coro_create(coro_context *ctx,
 
   makecontext (&(ctx->uc), (void (*)()) coro, 1, arg);
 
-#elif CORO_SJLJ || CORO_LOOSE
+#elif CORO_SJLJ || CORO_LOOSE || CORO_LINUX
 
 # if CORO_SJLJ
   stack_t ostk, nstk;
@@ -151,11 +151,29 @@ void coro_create(coro_context *ctx,
 
   sigprocmask (SIG_SETMASK, &osig, 0);
 
-# elif MS_LOOSE
+# elif CORO_LOOSE
 
-  coro_save (ctx);
+  setjmp (ctx->env);
   ctx->env[7] = (int)((char *)sptr + ssize);
-  ctx->env[8] = (int)coro;
+  ctx->env[8] = (int)coro_init;
+
+# elif CORO_LINUX
+
+  setjmp (ctx->env);
+#if defined(__GLIBC__) && defined(__GLIBC_MINOR__) \
+    && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined(JB_PC) && defined(JB_SP)
+  ctx->env[0].__jmpbuf[JB_PC] = (int)coro_init;
+  ctx->env[0].__jmpbuf[JB_SP] = (int)((char *)sptr + ssize);
+#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) \
+    && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 0 && defined(__mc68000__)
+  ctx->env[0].__jmpbuf[0].__aregs[0] = (long int)coro_init;
+  ctx->env[0].__jmpbuf[0].__sp = (int *)((char *)sptr + ssize);
+#elif defined(__GNU_LIBRARY__) && defined(__i386__)
+  ctx->env[0].__jmpbuf[0].__pc = (char *)coro_init;
+  ctx->env[0].__jmpbuf[0].__sp = (void *)((char *)sptr + ssize);
+#else
+#error "Unsupported Linux (g)libc version and/or platform"
+#endif
 
 # endif
 
diff --git a/coro.h b/coro.h
index dfde95f..56c11d2 100644
--- a/coro.h
+++ b/coro.h
@@ -57,8 +57,13 @@
  *    do it's job. Coroutine creation is much slower than UCONTEXT, but
  *    context switching is often a bit cheaper. It should work on almost
  *    all unices. Use this for GNU/Linux + glibc-2.2. glibc-2.1 and below
- *    do not work with any model (neither sigaltstack nor context functions
- *    are implemented)
+ *    do not work with any sane model (neither sigaltstack nor context
+ *    functions are implemented)
+ *
+ * -DCORO_LINUX
+ *
+ *    Old GNU/Linux systems (<= glibc-2.1) work with this implementation
+ *    (very fast).
  *
  * -DCORO_LOOSE
  *
@@ -108,9 +113,11 @@ void coro_transfer(coro_context *prev, coro_context *next);
  * That was it. No other user-visible functions are implemented here.
  */
 
-#if !defined(CORO_LOOSE) && !defined(CORO_UCONTEXT) && !defined(CORO_SJLJ)
+#if !defined(CORO_LOOSE) && !defined(CORO_UCONTEXT) \
+    && !defined(CORO_SJLJ) && !defined(CORO_LINUX)
 # if defined(WINDOWS)
 #  define CORO_LOOSE 1 /* you don't win with windoze */
+# elif defined(__linux) && defined(__x86)
 # elif defined(HAVE_UCONTEXT_H)
 #  define CORO_UCONTEXT 1
 # elif defined(HAVE_SETJMP_H) && defined(HAVE_SIGALTSTACK)
@@ -130,7 +137,7 @@ struct coro_context {
 
 #define coro_transfer(p,n) swapcontext(&((p)->uc), &((n)->uc))
 
-#elif CORO_SJLJ || CORO_LOOSE
+#elif CORO_SJLJ || CORO_LOOSE || CORO_LINUX
 
 #include <setjmp.h>
 
-- 
cgit v1.2.3