/** ------------------------------------------------------------- | Runs child processes in parallel on same processor as parent | and with same priority as parent. *-------------------------------------------------------------*/ void par(code_p code[], void *userArgs[], uint stacksize[], uint nc) { // current process is parent Process *parent = get_current(); // initialize barrier ParBarrier barrier; par_barr_init(&barrier, parent, nc); // enter preparing-to-wait state PREPARE_TO_WAIT(parent); // build and schedule each child process int i; for (i = 0; i < nc; i++) { Process *proc = make_process(run_in_par, code[i], (void *)&barrier, stacksize[i], parent->pri, parent->pun, userArgs[i]); enqueue(proc); } // barrier will awaken parent when all children are done relinquish(); }
/** ----------------------------------------------------------------- | Runs child processes in parallel on designated processors | with descending priorities starting with parent priority. *-----------------------------------------------------------------*/ void placed_par_pri( code_p code[], void *userArgs[], uint stacksize[], uint16 pun[], uint nc) { // see if there are too many child processes to fit priority scheme if (nc > PRI_PROCS) { plotz("Too many child processes"); } // current process is parent Process *parent = get_current(); // initialize barrier ParBarrier barrier; par_barr_init(&barrier, parent, nc); // child's priority level is parent's plus 1 int level = pri_level(parent->pri) + 1; // see if level exceeds allowable number of levels if (level > PRI_LEVELS) { plotz("Too many PRI levels"); } // enter preparing-to-wait state PREPARE_TO_WAIT(parent); // compute gap between child priorities int delta = pri_delta(level); // build and schedule each child process int i; int pri = parent->pri; for (i = 0; i < nc; i++) { Process *proc = make_process(run_in_par, code[i], (void *)&barrier, stacksize[i], priority(level, pri), pun[i], userArgs[i]); pri += delta; if (pun[i] == parent->pun) { enqueue(proc); } else { schedule(proc); } } // barrier will awaken parent when all children are done relinquish(); }
static OBJ hc_wait( pid_t pid, int options ) {OBJ r; OBJ cs; OBJ sig; OBJ cp; OBJ pr; int statloc; pid_t tmppid; tmppid=waitpid(pid,&statloc,options|WUNTRACED); if(tmppid==(pid_t)-1) { return_unix_failure(errno); } if(tmppid!=(pid_t)0) { if(WIFEXITED(statloc)) { if(WEXITSTATUS(statloc)==EXIT_SUCCESS) { copy_some(__AProcessCtrl_Asuccess,1); AWait_Aexited(__AProcessCtrl_Asuccess,cs); } else { copy_some(__AProcessCtrl_Afailure,1); AWait_Aexited(__AProcessCtrl_Afailure,cs); } } else { if(WIFSIGNALED(statloc)) { if(make_signal(WTERMSIG(statloc),&sig)) { copy_some(__AWait_AsignalledUnknown,1); cs=__AWait_AsignalledUnknown; } else { AWait_Asignalled(sig,cs); } } else { if(WIFSTOPPED(statloc)) { if(make_signal(WSTOPSIG(statloc),&sig)) { copy_some(__AWait_AstoppedUnknown,1); cs=__AWait_AstoppedUnknown; } else { AWait_Astopped(sig,cs); } } else { HLT("hc_wait\'Wait: Unknown process exit status"); } } } make_process(tmppid,cp); APair_S7(cp,cs,pr); if(options&WNOHANG) { AOption_Aavail(pr,r); } else { r=pr; } } else { if(options&WNOHANG) { copy_some(__AOption_Anil,1); r=__AOption_Anil; } else { HLT("hc_wait\'Wait: waitpid returns (pid_t)0 in blocking mode"); } } return_okay(r); }