lab7-fix2023/kernel/proc.c
2023-11-22 16:16:24 +08:00

138 lines
3.3 KiB
C

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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"
/*======================================================================*
schedule
*======================================================================*/
void schedule()
{
PROCESS* p;
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;
}
}
}
}
/*======================================================================*
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;i<NR_PCBS;i++)
{
if(p->task.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