1994-06-24 14:02:31 +00:00
|
|
|
|
/* $Id$ */
|
1987-02-24 18:36:02 +00:00
|
|
|
|
/* co.c - Routines to handle coroutines */
|
1987-02-25 16:41:09 +00:00
|
|
|
|
#include "ocm_proc.h"
|
1987-02-24 18:36:02 +00:00
|
|
|
|
|
|
|
|
|
static void search(), RESUMERR();
|
|
|
|
|
|
|
|
|
|
void resume(id) identification id;
|
|
|
|
|
/* Stops the current process, by saving its stack, and searches for the
|
|
|
|
|
* process with identification 'id' in the group the running process
|
|
|
|
|
* belongs to. If 'id' cannot be found then repeat these actions with
|
|
|
|
|
* the running process' parent. If 'id' is found it is activated. It
|
|
|
|
|
* is a fatal error if 'id' cannot be found.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
if (group!=nil) {
|
|
|
|
|
register wordsize size;
|
|
|
|
|
|
|
|
|
|
size=top_size(group->s_brk);
|
|
|
|
|
(*group->active)->stack=alloc((unsigned) size);
|
|
|
|
|
|
|
|
|
|
if (top_save(size, (*group->active)->stack))
|
|
|
|
|
search(id);
|
|
|
|
|
else {
|
|
|
|
|
free((*group->active)->stack);
|
|
|
|
|
load_betweens();
|
|
|
|
|
}
|
|
|
|
|
} else
|
|
|
|
|
RESUMERR();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void search(id) identification id;
|
|
|
|
|
/* Searches for the process with identification 'id'.
|
|
|
|
|
* If the process is found it is activated and its process tree is
|
|
|
|
|
* traversed to find the running process.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
register struct process **aproc, *proc;
|
|
|
|
|
|
|
|
|
|
for(;;) {
|
|
|
|
|
aproc= &group->first;
|
|
|
|
|
|
|
|
|
|
while (*aproc!=nil && (*aproc)->id!=id)
|
|
|
|
|
aproc= &(*aproc)->next;
|
|
|
|
|
|
|
|
|
|
if (*aproc!=nil) break;
|
|
|
|
|
|
|
|
|
|
save_between(group);
|
|
|
|
|
|
|
|
|
|
if ((group=group->up)==nil)
|
|
|
|
|
RESUMERR();
|
|
|
|
|
}
|
|
|
|
|
group->active=aproc;
|
|
|
|
|
proc= *aproc;
|
|
|
|
|
highest_group=group;
|
|
|
|
|
|
|
|
|
|
while (proc->down!=nil) {
|
|
|
|
|
group=proc->down;
|
|
|
|
|
proc= *group->active;
|
|
|
|
|
}
|
|
|
|
|
top_load(proc->stack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void delete_group(group) struct procgroup *group;
|
|
|
|
|
/* Removes the whole group and sub-groups recursively from the running
|
|
|
|
|
* process.
|
|
|
|
|
*/
|
|
|
|
|
{
|
|
|
|
|
register struct process *proc, *next;
|
|
|
|
|
|
|
|
|
|
proc=group->first;
|
|
|
|
|
|
|
|
|
|
while (proc!=nil) {
|
|
|
|
|
if (proc->down!=nil)
|
|
|
|
|
delete_group(proc->down);
|
|
|
|
|
else
|
|
|
|
|
free(proc->stack);
|
|
|
|
|
next=proc->next;
|
|
|
|
|
free( (void *) proc);
|
|
|
|
|
proc=next;
|
|
|
|
|
}
|
|
|
|
|
delete_between(group);
|
|
|
|
|
free( (void *) group);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void coend()
|
|
|
|
|
{
|
|
|
|
|
register struct process *proc, *next;
|
|
|
|
|
register struct procgroup *junk;
|
|
|
|
|
|
|
|
|
|
proc=group->first;
|
|
|
|
|
|
|
|
|
|
while (proc!=nil) {
|
|
|
|
|
if (proc!= *group->active) {
|
|
|
|
|
if (proc->down!=nil)
|
|
|
|
|
delete_group(proc->down);
|
|
|
|
|
else
|
|
|
|
|
free(proc->stack);
|
|
|
|
|
}
|
|
|
|
|
next=proc->next;
|
|
|
|
|
free( (void *) proc);
|
|
|
|
|
proc=next;
|
|
|
|
|
}
|
|
|
|
|
delete_between(group);
|
|
|
|
|
junk=group;
|
|
|
|
|
group=group->up;
|
|
|
|
|
free( (void *) junk);
|
|
|
|
|
|
|
|
|
|
if (group!=nil)
|
|
|
|
|
(*group->active)->down=nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void RESUMERR()
|
|
|
|
|
{
|
|
|
|
|
write(2, "RESUMERR\n", 9);
|
|
|
|
|
abort();
|
|
|
|
|
}
|