/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ proc.c ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Forrest Yu, 2005 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ #include "type.h" #include "const.h" #include "protect.h" #include "string.h" #include "proc.h" #include "global.h" #include "proto.h" #include "stdio.h" /*======================================================================* schedule *======================================================================*/ void schedule() { PROCESS* p; #ifdef USE_FBCON for (int i = NEXT(p_proc_current->task.pid, NR_PCBS); i != p_proc_current->task.pid; i = NEXT(i, NR_PCBS)) { if (proc_table[i].task.stat == READY) { p_proc_next = &proc_table[i]; return; } } p_proc_next = p_proc_current; #else int greatest_ticks = 0; //Added by xw, 18/4/21 if (p_proc_current->task.stat == READY && p_proc_current->task.ticks > 0) { p_proc_next = p_proc_current; //added by xw, 18/4/26 return; } while (!greatest_ticks) { for (p = proc_table; p < proc_table+NR_PCBS; p++) //edit by visual 2016.4.5 { if (p->task.stat == READY && p->task.ticks > greatest_ticks) //edit by visual 2016.4.5 { greatest_ticks = p->task.ticks; // p_proc_current = p; p_proc_next = p; //modified by xw, 18/4/26 } } if (!greatest_ticks) { for (p = proc_table; p < proc_table+NR_PCBS; p++) //edit by visual 2016.4.5 { p->task.ticks = p->task.priority; } } } #endif } /*======================================================================* alloc_PCB add by visual 2016.4.8 *======================================================================*/ PROCESS* alloc_PCB() {//分配PCB表 PROCESS* p; int i; p=proc_table+NR_K_PCBS;//跳过前NR_K_PCBS个 for(i=NR_K_PCBS;itask.stat==IDLE)break; p++; } if(i>=NR_PCBS) return 0; //NULL else return p; } /*======================================================================* free_PCB add by visual 2016.4.8 *======================================================================*/ void free_PCB(PROCESS *p) {//释放PCB表 p->task.stat=IDLE; } /*======================================================================* yield and sleep *======================================================================*/ //used for processes to give up the CPU void sys_yield() { p_proc_current->task.ticks = 0; /* modified by xw, 18/4/27 */ sched(); //Modified by xw, 18/4/19 } //used for processes to sleep for n ticks void sys_sleep(int n) { int ticks0; ticks0 = ticks; p_proc_current->task.channel = &ticks; while(ticks - ticks0 < n){ p_proc_current->task.stat = SLEEPING; // save_context(); sched(); //Modified by xw, 18/4/19 } } /*invoked by clock-interrupt handler to wakeup *processes sleeping on ticks. */ void sys_wakeup(void *channel) { PROCESS *p; for(p = proc_table; p < proc_table + NR_PCBS; p++){ if(p->task.stat == SLEEPING && p->task.channel == channel){ p->task.stat = READY; } } } //added by zcr int ldt_seg_linear(PROCESS *p, int idx) { struct s_descriptor * d = &p->task.ldts[idx]; return d->base_high << 24 | d->base_mid << 16 | d->base_low; } void* va2la(int pid, void* va) { if(kernel_initial == 1){ return va; } PROCESS* p = &proc_table[pid]; u32 seg_base = ldt_seg_linear(p, INDEX_LDT_RW); u32 la = seg_base + (u32)va; return (void*)la; } //~zcr