Longjmping back, and back again; Coroutines in C

Peter Desnoyers desnoyer at apple.com
Thu Nov 23 05:24:44 AEST 1989


In article <28112 at amdcad.AMD.COM> tim at proton.amd.com (Tim Olson) writes:
> In article <457 at enea.se> jerker at helios.se (Jerker W}gberg) writes:
> | 
> | I am trying to implement coroutines using plain C. My
> | application is not time critical, so there is no need for speed,
> | being portable is far more important. It would be great if there
> | was a way to switch stacks of the processes using just C.
> 
> Sorry, but there just isn't a way that is portable to all
> architectures; there is almost always some assembly-language involved.

You can swap the stack without using assembler by either:

  + using pseudo-variables for registers (I've only seen this feature
    in Turbo C for the peecee)

  + /* KLUDGE ALERT */ swapping the stack pointer (and usually base
    ptr as well) field in a jmpbuf. E.g.:

      if (setjmp( buf) != 0)
        task_to_spawn()
      buf[x] = malloc(stacksize);
      buf[y] = buf[x] {+-} zzz;
      longjmp(buf);

This is even more non-portable than assembler, as it is almost guaranteed 
not to be portable between compatible compilers on the same machine, or 
even between upgrades of the same compiler. If you don't have an 
assembler, however, it may be the only way. 

>>[CPUs that will give problems with this?]
> Here's an example of one:  The Am29000 (32-bit RISC processor) uses a
> large number of registers as a "stack cache", and spills and fills
> these to/from an area in memory when it overflows.  

Problems like this (and register arguments) can (usually) be handled in a 
non-portable way with dummy arguments and dummy local variables, forcing 
the values you care about to be spilled to memory.

                                      Peter Desnoyers
                                      Apple ATG
                                      (408) 974-4469



More information about the Comp.lang.c mailing list