raghavan@umn-cs.cs.umn.edu (Vijay Raghavan) (03/14/88)
Let me make it clear that this is *not* a feature that I want to see in D, or anything like that. I think that if co-routines are desired, a programmer can implement them on his own in C, with about the amount of portability that setjmp and longjmp have. I do have such an implementation (which, of course, I've never really had to use, except to satisfy myself that it works.) My problem is that I don't *like* the implementation. There is a particular bit of dirty coding which I can't seem to get around no matter how I shift and squirm. I think that this is a peculiar situation where one *has* to resort to a little bit of kludgery in order to get the job done. But maybe I'm wrong. How would *you* code the functions "instantiate" and "resume" to make the following program work? Remember, you have to write the functions all in C, no assembler allowed. Of course, you may reasonably ask what the functions are supposed to do in the first place, but I think the code and choice of names makes that clear. The program uses the Sieve of Eratosthenes to generate prime numbers. Whenever a prime number is discovered, a new "filter" coroutine is instantiated, which tests whether future numbers generated by "gennum" are multiples. You may assume that whenever *any* co-routine terminates, so does the whole program. ---------------------------------------------- Cut here --------------- #include <stdio.h> #define MAXPRIMES 10000 char * handle, *instantiate(); int number = 1, primes = 0, maxprimes = MAXPRIMES; main(argc, argv) int argc; char ** argv; { int gennum(); if (argc >= 2) maxprimes = atoi(argv[1]); handle = instantiate (gennum); resume (handle); } gennum() { int filter(); char * filterhandle = instantiate(filter); for(;;) { ++ number; resume (filterhandle); } } filter() { int mine; char * myfilter = NULL; primes ++; printf ("Prime #%d is %d\n", primes, mine = number); while (primes < maxprimes) if (number % mine) { if (myfilter == NULL) myfilter = instantiate (filter); resume (myfilter); } else resume (handle); } ------------------------------ Cut here ------------------------- Vijay Raghavan
edk@gryphon.CTS.COM (Ed Kaulakis) (03/20/88)
In article <4326@umn-cs.cs.umn.edu>, raghavan@umn-cs.cs.umn.edu (Vijay Raghavan) writes: > > Let me make it clear that this is *not* a feature that I want > to see in D, or anything like that. I think that if co-routines > are desired, a programmer can implement them on his own in C, > with about the amount of portability that setjmp and longjmp > have. I do have such an implementation (which, of course, I've > never really had to use, except to satisfy myself that it > works.) My problem is that I don't *like* the implementation. There > is a particular bit of dirty coding which I can't seem to get > around no matter how I shift and squirm. I think that this is > a peculiar situation where one *has* to resort to a little bit of > kludgery in order to get the job done. But maybe I'm wrong. How > would *you* code the functions "instantiate" and "resume" to make > the following program work? > Well, my opinion is that it can't be done in pure C, which doesn't know anything about its own stack pointer. The stack pointer *must* be manipulated to give a coroutine the same kind of syntactic sugar on offset references to its activation record (a mechanism often thought of as "auto" variable allocation) that is enjoyed by regular C functions. Thus any coroutining code must kludgily mess with a hardware thingy that's not even declarable, for bizarre side-effect.