From Modula to Oberon
Peter da Silva
peter at sugar.UUCP
Fri Mar 25 23:06:36 AEST 1988
In article <1139 at PT.CS.CMU.EDU>, edw at IUS1.CS.CMU.EDU (Eddie Wyatt) writes:
>>
>> The debate about CLU iterators misses an important point: CLU iterators are
>>coroutines, which C does not have.
Coroutines in 'C' are easy to implement, though. Why, this whole O/S we're
reading news on (UNIX) is written as a set of coroutines in 'C'. (yes, it's
a simplification... but not much of one).
I'd like to see the following functions become standard in 'C':
COROUTINE -- Build a jmp_buf for a coroutine.
int coroutine(jump, entry, stack, stacksize);
struct jmp_buf *jump;
void (*entry)();
char *stack;
int stacksize;
This sets up the stack and jmp_buf so that a call to "longjmp(jmp_buf)"
will appear to be a call to entry(). It will return an error only if the
stack isn't large enough for a small routine that does nothing but call
the following function:
int switch(from, to, status)
struct jmp_buf *from, *to;
int status;
{
int code;
if(!(code=setjmp(from)))
longjmp(to, status);
return code;
}
Voila! Co-routines! Lightweight processes (best if you have the Berkeley
signal handler, I guess, so you could run it off alarms...):
struct proc {
struct proc *next;
struct proc *prev;
char *stack;
struct jmp_buf context;
};
struct proc *runq; /* doubly linked circular queue */
sleep()
{
struct proc *self;
/* do nothing if no procs or I'm alone */
if(!runq)
return;
if(runq->next == runq)
return;
self = runq;
runq = runq->next;
switch(&self->context, &runq->context, 1);
}
int spawn(entry, stacksize)
void (*entry)();
int stacksize;
{
struct proc *p;
if(!(p = malloc(sizeof *p)))
return 0;
if(!(p->stack = malloc(stacksize))) {
free(p);
return 0;
}
if(!coroutine(p, entry, p->stack, stacksize)) {
free(p->stack);
free(p);
return 0;
}
p->stacksize = p;
p->next = runq->next;
p->prev = runq;
runq->next->prev = p;
runq->next = p;
return p;
}
int delete(p) /* note, this version doesn't allow a process to delete itself! */
struct process *p;
{
if(p==runq)
return 0;
p->next->prev = p->prev;
p->prev->next = p->next;
free(p->stack);
free(p);
}
--
-- Peter da Silva `-_-' ...!hoptoad!academ!uhnix1!sugar!peter
-- Disclaimer: These U aren't mere opinions... these are *values*.
More information about the Comp.unix.wizards
mailing list