📄 concur.c
字号:
/* Zobifie the process */ cur_proc->stat = SZOMB; /* Remove any locks */ cur_proc->flag = 0; /* Ignore any pending signals */ cur_proc->sig = 0; /* Find any children and give them the to the grand person of * the process. */ child = &proc_table[0]; for(pid = 0; pid < NPROC; pid++){ if(child->ppid == cur_proc->pid){ child->ppid = cur_proc->ppid; } child++; } /* Realeses process memory segment for use */ endmem(cur_proc->majseg, cur_proc->minseg); cur_proc->majseg = cur_proc->minseg = 0; smaskoff(cur_proc,smask); /* Renables process switch */ return 0;}/* * Wakeon() Sets the prewakeup event, if this event occurs * and then the process goes to sleep on the event * the process will be immediatly re-awoken. * Returns the status of the prewake event flag, * 0 if the previous event has'nt occured 1 if it has. */wakeon(chan)caddr_t chan;{ int event; short imask; imask = spl6(); /* Stops interrupts */ /* Gets prewake event flag if wakeon is for the same event */ if(chan == cur_proc->pwakechan) event = cur_proc->pwakeevent; else event = 0; cur_proc->pwakechan = chan; /* Sets new prewakechan value */ cur_proc->pwakeevent = 0; splx(imask); /* Recovers interrupts */ return event;}/* * Sleep() Send process to sleep * * * Will send a process to sleep awaiting the event as given (chan). * If the process is awoken by a signal which returns, then the * call will return with the signal number, else it will return with 0. */sleep(chan, pri)caddr_t chan;int pri;{ short smask, imask; int sig;#ifdef TCONCURprintf("Sleep on chan %x, pri %d\n",chan,pri);#endif /* Check if there are any signals if so do them *//* checkev(EVALLSIG); */ smask = smaskon(cur_proc, EVALL); /* Disables process switch */ imask = spl6(); /* Disable interrupts */ sig = 0; /* Signal number awoken by */ /* Checks if the event has been pre-empted if so return */ if((cur_proc->pwakechan == chan) && cur_proc->pwakeevent){ cur_proc->pwakeevent = 0; /* Acknowledge the event */ cur_proc->pwakechan = 0; /* Turn off pre-empt */ splx(imask); /* Renables interrupts */ smaskoff(cur_proc,smask); /* Renables process switch */ return 0; } cur_proc->wchan = chan; /* Sets up event */ cur_proc->pri = pri; splx(imask); /* Renables interrupts */#ifdef TCONCURprintf("Sleep about to switch\n");#endif /* Switch to new process no preference, if process hasn't been awoken */ while(cur_proc->wchan){ cur_proc->stat = SSLEEP; /* Sends process to sleep */ /* Switches to new process if user caught signal processed * and sleeping on pause, return signal number */ if((sig = pswitch(-1)) && (cur_proc->wchan == (caddr_t)1)){ cur_proc->wchan = 0; cur_proc->pwakeevent = 0; /* Acknowledge the event */ cur_proc->pwakechan = 0; /* Turn off pre-empt */ smaskoff(cur_proc,smask); /* Renables process switch */ return sig; } } cur_proc->pwakeevent = 0; /* Acknowledge the event */ cur_proc->pwakechan = 0; /* Turn off pre-empt */ smaskoff(cur_proc,smask); /* Renables process switch */#ifdef TCONCURprintf("Sleep returned from switch\n");#endif return 0;}/****************************************************************************** * Wakeup() Flag wakeup process ****************************************************************************** * * Flags processes to wake up but does not actualy wake them up. * They will wake on the next or later process switch. */wakeup(chan)caddr_t chan;{ register short pid; register struct procs *proc; proc = &proc_table[0]; for(pid = 0; pid < NPROC; pid++){ /* Checks if valid process */ if(proc->stat && (proc->stat != SZOMB)){ /* Check if process is sleeping on this event */ if(proc->wchan == chan){ proc->wchan = 0; proc->stat = SRUN; /* If waking up high-priority process indicate * Process switch is required */ if(proc->pri <= PUSERMIN) swtchflag = 1; } /* Checks if process is pre-empting this event */ if(proc->pwakechan == chan){ proc->pwakeevent = 1; } } proc++; } return;}/****************************************************************************** * Wakeupp() Flag wakeup given process ****************************************************************************** * * Flags process given to wake up but does not actualy wake them up. * They will wake on the next or later process switch. */wakeupp(pid, chan)int pid;caddr_t chan;{ register struct procs *proc; proc = &proc_table[pid]; /* Checks if valid process */ if(proc->stat && (proc->stat != SZOMB)){ /* Check if process is sleeping on this event */ if(proc->wchan == chan){ proc->wchan = 0; proc->stat = SRUN; /* If waking up high-priority process indicate * Process switch is required */ if(proc->pri <= PUSERMIN) swtchflag = 1; } /* Checks if process is pre-empting this event */ if(proc->pwakechan == chan){ proc->pwakeevent = 1; } } return;}/****************************************************************************** * Pswitch() Process switch change processes ****************************************************************************** * * Argument passed to pswitch contains the process number * to switch to, if -1 then there is no preference and pswitch() * will search for the highest priority process to run. * When this is found it will scan though for the next process in * the process table that has this priority, thus processes with * equal prioritys will be executed in round robin fashion. * Note pre-emting high priority processes will mess up this system * So process prioritys should be adjusted depending on the * time they occupied the CPU. * Note is a signal is found the whole process will be swaped in * even if it is going to be killed this is a bit time consuming and * wastfull. The signal will be processed on the returning system * call, or on returning back to sleep. * This routine calla via the swtch wrapper pswtch to change to a * new process, the events are :- * swtch - saves proc pointer in d0 calls trap #1 * trap #1 - calls wrapper which saves process state, calls pswtch * pswtch - changes to new process and returns * * Checks signals for process when new process is restarted * Returns 0 normaly, or the signal number if a user caught signal * was processed. */# define LOWPRI 0x7FFF /* Lowest priority */pswitch(reqpid)int reqpid;{ register char found; register short pid, hpri; register struct procs *proc; short smask, intmask; struct procs *oproc;#ifdef TPSWITCHprintf("Pswitch got here given %d %x %x\n",reqpidcur_proc->reg->sr,cur_proc->reg->pc);#endif /* Disable process switching */ smask = smaskon(cur_proc, EVALL); oproc = cur_proc; /* Indicate process switch has occured */ swtchflag = 0; /* Allow interupts to ocurr */ intmask = spl0(); /* Continue round this loop until a process is found * exits with proc pointing to process */ found = 0; while(!found){ /* Check if a valid process id is has been given if so * choose this one as the next process */ if((reqpid < NPROC) && (reqpid >= 0)){ proc = &proc_table[reqpid]; if((proc->stat == SRUN) || (proc->stat == SSLEEP)){ found++; break; } } /* Search for higest priority process */ hpri = LOWPRI; proc = &proc_table[0]; for(pid = 0; pid < NPROC; pid++){ if(proc->stat == SRUN){ if(proc->pri < hpri) hpri = proc->pri; found++; } proc++; } /* If no process wants to run continue in wait loop */ if(!found) continue; /* Go through table from curent process upwards, looking for * a proccess with this priority that wants to run. * Continue back through 0 to curent process. */ proc = cur_proc; do{ /* Increments to next entry in process table */ proc++; /* Checks if last process in table is so go * to begining */ if(proc->pid >= NPROC){ /* Next process is 0 wrap-around */ proc = &proc_table[0]; } /* If running process has this priority set found flag*/ if((proc->stat == SRUN) && (proc->pri == hpri)) break; } while(proc != cur_proc); } /* Found one so go get it going first stop interupts */ splx(intmask); /* Check if the process is in core if so continue with new process */ /* Note if MMU is added then will have to check here if process is * mapped into core if not map it in (call mmuset(pid) in mmu.c) */ if(!(proc->flag & SLOAD)){#ifdef TPSWITCHprintf("PSWITCH: Swaping out process %d\n",cur_proc->pid);#endif /* Get an area of core for the process */ if((proc->minseg = getmem(proc->majseg, 0)) == -1){ proc = cur_proc; } /* Swaps in new process if possible */ else{#ifdef TPSWITCHprintf("PSWITCH: Swaping in process %d\n",proc->pid);#endif if(swapin(proc)){ printf("PSWTCH: Cannot swap in new process %s\n" , proc->name); smaskoff(cur_proc,smask); return -1; } } } /* Sets to new process and executes it */ /* Sets process priority */ proc->pri = PUSER; proc->stat = SRUN; /* Make sure new process will run for a while */ swtchflag = 0; tickcount = TPERSWITCH; /* Set to new process and reset switch mask */ swtch(proc); smaskoff(oproc,smask);#ifdef TPSWITCHprintf("Pswitch about to execute %d %x %x\n",cur_proc->pid,cur_proc->reg->sr,cur_proc->reg->pc);#endif /* Checking if any events have occured to stop this process */ return checkev(EVALLSIG);}/* * Smaskon() Appends the new masking level to the software mask */smaskon(proc, smask)struct procs *proc;short smask;{ short smasko; smasko = proc->smask; proc->smask |= smask; return smasko;}/* * Smaskoff() Sets the software mask to the given value */smaskoff(proc, smask)struct procs *proc;short smask;{ short smasko; smasko = proc->smask; proc->smask = smask; return smasko;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -