Initial revision
This commit is contained in:
92
lang/occam/lib/par.c
Normal file
92
lang/occam/lib/par.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/* par.c - Routines to simulate parallelism */
|
||||
#include "process.h"
|
||||
|
||||
static void search_next(), DEADLOCK();
|
||||
|
||||
void resumenext()
|
||||
/* Stops the current process, by saving its stack, and determines a new one
|
||||
* to restart. In case the root of the process tree is passed more then once,
|
||||
* without a process having done something useful, we'll have a deadlock.
|
||||
*/
|
||||
{
|
||||
if (group!=nil) {
|
||||
register struct process *proc= *group->active;
|
||||
register wordsize size;
|
||||
|
||||
size=top_size(group->s_brk);
|
||||
proc->stack=alloc((unsigned) size);
|
||||
|
||||
if (top_save(size, proc->stack)) {
|
||||
group->active= &proc->next;
|
||||
search_next();
|
||||
} else {
|
||||
free(proc->stack);
|
||||
load_betweens();
|
||||
}
|
||||
} else
|
||||
if (++deadlock>1) DEADLOCK();
|
||||
}
|
||||
|
||||
static void search_next()
|
||||
/* Tries to resume the active process, if this is not possible, the process
|
||||
* tree will be searched for another process. If the process tree is fully
|
||||
* traversed, search will restart at the root of the tree.
|
||||
*/
|
||||
{
|
||||
while (*group->active==nil && group->up!=nil) {
|
||||
save_between(group);
|
||||
|
||||
group=group->up;
|
||||
|
||||
group->active= &(*group->active)->next;
|
||||
}
|
||||
|
||||
if (*group->active==nil) {
|
||||
if (++deadlock>1) DEADLOCK();
|
||||
group->active= &group->first;
|
||||
}
|
||||
|
||||
highest_group=group;
|
||||
|
||||
while ((*group->active)->down!=nil) {
|
||||
group=(*group->active)->down;
|
||||
group->active= &group->first;
|
||||
}
|
||||
top_load((*group->active)->stack);
|
||||
}
|
||||
|
||||
void parend()
|
||||
/* Deletes the current process from its process group and searches for a new
|
||||
* process to run. The entire group is removed if this is the last process in
|
||||
* the group, execution then continues with the process that set up this group
|
||||
* in the first place.
|
||||
*/
|
||||
{
|
||||
register struct process *junk;
|
||||
|
||||
junk= *group->active;
|
||||
*group->active=junk->next;
|
||||
free((void *) junk);
|
||||
|
||||
if (group->first==nil) {
|
||||
register struct procgroup *junk;
|
||||
|
||||
delete_between(group);
|
||||
|
||||
junk=group;
|
||||
group=group->up;
|
||||
free((void *) junk);
|
||||
|
||||
if (group!=nil)
|
||||
(*group->active)->down=nil;
|
||||
} else {
|
||||
deadlock=0;
|
||||
search_next();
|
||||
}
|
||||
}
|
||||
|
||||
static void DEADLOCK()
|
||||
{
|
||||
write(2, "DEADLOCK\n", 9);
|
||||
abort();
|
||||
}
|
||||
Reference in New Issue
Block a user