diff options
| author | root <root> | 2001-07-24 19:52:55 +0000 | 
|---|---|---|
| committer | root <root> | 2001-07-24 19:52:55 +0000 | 
| commit | 283d85ff0a0b7248c125a87c83aff889c7061a25 (patch) | |
| tree | 368b082dda06aec787d1df610ec30340507fd6e5 | |
| parent | 51892b0d79d391a11276d1020e7c1ec91b6a05a4 (diff) | |
*** empty log message ***
| -rw-r--r-- | coro.c | 28 | ||||
| -rw-r--r-- | coro.h | 15 | 
2 files changed, 34 insertions, 9 deletions
| @@ -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 @@ -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> | 
