lowindex=j;
if(lowindex!
=i)
{
resetBK(i*t,l,l+*(arry+i));
resetBK(lowindex*t,l,l+*(arry+lowindex));
inttemp=arry[i];
arry[i]=arry[lowindex];
arry[lowindex]=temp;
draw(i*t,l,l+*(arry+i));
draw(lowindex*t,l,l+*(arry+lowindex));
}
}
}
线程控制块tcb中增加nice属性,在函数sys_task_create中初始化nice=0
/*
系统调用getpriority的执行函数
获取当前线程的优先级
*/
intsys_getpriority(inttid)
{
if(tid==0)returng_task_running->nice+NZERO;//获取当前线程的nice值
uint32_tflags;structtcb*tsk;
save_flags_cli(flags);
tsk=get_task(tid);
restore_flags(flags);
returntsk->nice+NZERO;//获取线程的nice值
}
/*
系统调用setpriority的执行函数
调整当前线程的优先级
*/
//把线程tid的nice设为(prio-NZERO)
intsys_setpriority(inttid,intprio)
{
uint32_tflags;structtcb*tsk;
if(tid==0){
save_flags_cli(flags);
g_task_running->nice=prio-20;//设置当前线程的nice值
restore_flags(flags);
return0;
}
//if(tsk==NULL)return-1;
if(prio<0)prio=0;//prio必须在[0,2*NZERO-1]
if(prio>40)prio=40;
save_flags_cli(flags);
tsk=get_task(tid);//用save_flags_cli/restore_flags保护
restore_flags(flags);
tsk->nice=prio-20;//设置线程的nice值
return0;
}
把这两个个函数做成系统调用,分别是getpriority(inttid),setpriority(inttid,intprio)
静态调度schedule:
voidschedule(){
structtcb*select=g_task_head;
structtcb*my_select=g_task_running;
while(select!
=NULL){
if((select->tid!
=0)&&(select->state==TASK_STATE_READY))
{
//if(my_select==NULL){my_select=select;continue;}
if(select->nice<=my_select->nice)//选择等待队列里的线程优先级高的
my_select=select;
if(my_select->tid==0){//跳过task0运行
my_select=select;
}
}
select=select->next;
}
if(my_select==g_task_running){
if(g_task_running->state==TASK_STATE_READY)
return;
my_select=task0;//仅当没有其他可运行的线程时,才能调度
}
g_resched=0;
switch_to(my_select);
}
线程控制块tcb中
增加estcpu属性,在函数sys_task_create中初始化estcpu=0;
增加priority属性,在函数sys_task_create中初始化priority=0;
timer.c中增加全局变量g_load_avg:
表示系统的平均负荷
用浮点(float-point)表示g_load_avg和estcpu:
精度高,效率低
动态调度schedule:
voidschedule()
{
structtcb*select=g_task_head;
structtcb*my_select=g_task_running;
while(select!
=NULL)
{
select->priority=127-fixedpt_toint(fixedpt_div(select->estcpu,fixedpt_fromint(4)))-select->nice*2;//计算所有线程的priority
select=select->next;
}
//动态优先级
select=g_task_head;
while(select!
=NULL){
if((select->tid!
=0)&&(select->state==TASK_STATE_READY)){
if(my_select->prioritypriority)
{
my_select=select;//选择等待队列里的线程优先级高的
}
elseif(my_select->tid==0)
{
my_select=select;
}
}
select=select->next;
}
if(my_select==g_task_running){
if(my_select->state==TASK_STATE_READY)
return;
my_select=task0;
}
printk("0x%d->0x%d\r\n",(g_task_running==NULL)?
-1:
g_task_running->tid,select->tid);
g_resched=0;
switch_to(my_select);
}
timer.c中添加如下
g_task_running->estcpu=fixedpt_add(g_task_running->estcpu,FIXEDPT_ONE);//计算线程使用CPU时间estcpu
if(g_timer_ticks%HZ==0){//每隔一秒计算一次
intnready=0;//表示处于就绪状态的线程个数
structtcb*my_select=g_task_head;
intnice;//g_task_running->nice;
//my_select=g_task_head;
fixedptratio;
while(my_select!
=NULL){
if(my_select->state==TASK_STATE_READY)nready++;
nice=my_select->nice;
ratio=fixedpt_mul(FIXEDPT_TWO,g_load_avg);//每秒钟为所有线程(运行、就绪和等待)更新一次
ratio=fixedpt_div(ratio,fixedpt_add(ratio,FIXEDPT_ONE));
my_select->estcpu=fixedpt_add(fixedpt_mul(ratio,my_select->estcpu),
fixedpt_fromint(nice));
my_select=my_select->next;
}
fixedptr59_60=fixedpt_div(fixedpt_fromint(59),fixedpt_fromint(60));//计算系统的平均负荷g_load_avg
fixedptr01_60=fixedpt_div(FIXEDPT_ONE,fixedpt_fromint(60));
g_load_avg=fixedpt_add(fixedpt_mul(r59_60,g_load_avg),
fixedpt_mul(r01_60,fixedpt_fromint(nready)));
}
主函数:
intmode=0x0118;
initGraphics(mode);
inty=0;
for(y=0;ysetPixel(g_mib.XResolution/3,y,RGB(0,125,125));
setPixel(g_mib.XResolution/3*2,y,RGB(0,125,125));
}
int*pcode_exit;
//申请用户栈
unsignedchar*stack_foo1=(unsignedchar*)malloc(1024*1024);
unsignedchar*stack_foo2=(unsignedchar*)malloc(1024*1024);
unsignedchar*stack_foo3=(unsignedchar*)malloc(1024*1024);
unsignedchar*stack_foo4=(unsignedchar*)malloc(1024*1024);
inttid_foo1,tid_foo2,tid_foo3;
setpriority(0,8);
//创建冒泡排序线程函数1
tid_foo1=task_create(stack_foo1+1024*1024,tsk_foo_line1,(void*)0);
setpriority(tid_foo1,1);
//创建选择排序线程函数2
tid_foo2=task_create(stack_foo2+1024*1024,tsk_foo_line2,(void*)0);
setpriority(tid_foo2,10);
//创建插入排序线程函数3
tid_foo3=task_create(stack_foo3+1024*1024,tsk_foo_line3,(void*)0);
setpriority(tid_foo3,8);
setpriority(0,35);
//用户栈释放
task_wait(tid_foo1,pcode_exit);
free(stack_foo1);
task_wait(tid_foo2,pcode_exit);
free(stack_foo2);
task_wait(tid_foo3,pcode_exit);
free(stack_foo3);
五、实验结果及分析(实现的效果,包括屏幕截图、系统总体运行情况和测试情况等)
静态优先级:
动态优先级: