pintos pro1.docx
- 文档编号:24603840
- 上传时间:2023-05-29
- 格式:DOCX
- 页数:25
- 大小:1.95MB
pintos pro1.docx
《pintos pro1.docx》由会员分享,可在线阅读,更多相关《pintos pro1.docx(25页珍藏版)》请在冰豆网上搜索。
pintospro1
Pintosproject1设计与实现
作者:
西安电子科技大学 王永刚QQ:
357543420
以下两个的题目理解和算法描述在另两个文件中
2.2.2AlarmClock
thread.h文件中
1.在结构structthread中增加了成员
int64_tblock_ticks;小于0表示无限等待
timer.c文件中time_sleep函数中
2.删除了原来的忙等待
while(imer_elapsed(start) thread_yield(); 3.加入了 void timer_sleep(int64_tticks) { if(ticks<=0) return; int64_tstart=timer_ticks(); enumintr_levelold_level; ASSERT(intr_get_level()==INTR_ON); //while(timer_elapsed(start) //thread_yield(); structthread*t=thread_current();//setblocktime t->block_ticks=ticks; old_level=intr_disable(); thread_block();//blockitself intr_set_level(old_level); thread_yield(); } 4.在thread.h中定义了block_check()函数 在thread.c中实现了 voidblock_check(structthread*t,void*aux) { if(t->status==THREAD_BLOCKED&&t->block_ticks>0) { t->block_ticks--; if(t->block_ticks==0) thread_unblock(t); } } 5.在time.c文件中time_interrupt()函数中 加入: thread_foreach(block_check,NULL); 2.2.3依据优先级排队,在ready_list中和BlockList中都要排序采用插入排序 1.在thread.c中(在thread.h中申明) 加入: 依据优先级比较 /*listcomparedbypriority<*/ boolless_priority(conststructlist_elem*a, conststructlist_elem*b, void*aux) { conststructthread*t1=list_entry(a,structthread,allelem); conststructthread*t2=list_entry(b,structthread,allelem); returnt1->priority } 2.在thread.c中, thread_yield()函数中修改 list_insert_ordered(&ready_list,&cur->elem,less_priority,NULL); //list_push_back(&ready_list,&cur->elem); 3.在thread.c中 thread_unblock()函数中 修改: //list_push_back(&ready_list,&t->elem); list_insert_ordered(&ready_list,&t->elem,less_priority,NULL); 4.在thread_create()中 在thread_unblock(t)后面加入了 thread_yield(); 如果新产生的进程优先及高与当前进程,那么新进程在read_list中的位置前与当前进程。 5.修改了synch.c中 seam_down() //list_push_back() 为list_insert_ordered() while(sema->value==0) { //list_push_back(&sema->waiters,&thread_current()->elem); list_insert_ordered(&sema->waiters,&thread_current()->elem,less_priority,NULL); thread_block(); } 对cond_wait()函数做同样修改 waiter.current_thread=thread_current(); list_insert_ordered(&cond->waiters,&waiter.elem,less_priority,(void*)1); /*Onesemaphoreinalist.*/ structsemaphore_elem { structlist_elemelem;/*Listelement.*/ structsemaphoresemaphore;/*Thissemaphore.*/ structthread*current_thread;/*waitthread*/ }; 此结构在synch.c中,移动到了sych.h中,并加入了 structthread*current_thread;/*waitthread*/ Priority-Donation 1.如果有优先级分别为高中低的三个线程H,M,L.如果H需要等待L(因为L占有锁),而M此时在ready_list中,如果按照优先级高低调度,那么H永远得不到CPU,因为L永远得不到CPU。 解决方法是: H将自己的优先级先给L(当L占有锁的时候),但是L释放锁后应立即调整回他原来的优先级。 实现优先级捐赠需要考虑的情况: 1.只针对锁(lock)实现,其他的同步机制不用,如semaphore和condtion不用 2.单一捐赠priority-donation-one即一个进程级另一个进程捐赠 3.多重捐赠priority-donation-multiple即多个进程给一个进程捐赠 4.还有嵌套捐赠priority-donation-nested 如果H因为一把锁在等待M(因为M恰好占用了这把锁),而M又因为一把锁在等待L.这时L和M的优先级都应该变为H的优先级。 可以假设嵌套深度不超过8层。 5.当一个线程得到捐献的优先级时,自己如果再通过priority设置自己的优先级,那就不能改变优先级,应该保存起来。 一种实现方法: (1)要求低优先级线程L得到捐赠后,再释放锁后要恢复自己原来的优先级,所以改变的L优先级时,对之前的优先级就保存下来。 可以在structthread结构中加入数组pri_stack[]保存: structPriStore { intpri;/*保存原来的优先级*/ structsemaphore*s;/*保存下优先级是因为该线程占有哪个semaphore而改变的*/ }; structPriStorepri_stack[MAX_DEEP];/*usedinprioritydonate*/ inttop;/*数组中元素数,把此数组当栈用*/ 至于数组大小暂且定为#defineMAX_DEEP25 这样1,2两种情况都解决 (2)第3种情况要求嵌套改变优先级 所以每个进程要保存下自己被阻塞的原因 在structthread中加入了 structsemaphore*block_reason; 记录线程是被哪个semaphore阻塞。 记录下阻塞原因后,当H因为一把锁在等待M,而M也处于阻塞态时,就可以知道M再等哪把锁K,然后遍历所以进程看谁持有这把锁K,进而递归改变优先级以实现priority-donate-nested. 此时为了知道谁占用这把锁K,所以每个线程获得semaphore后都要记录下来,这时又用一个数组记录 #defineMAX_SEMA25 structGetedSema { structsemaphore*s;//占有的sema intn;//同一semaphore可能被同一线程占有多个,但是,锁只能被占有一次。 }; structGetedSemags[MAX_SEMA];// intm_gs;//占用sema种类数。 (3)对于情况5,在structthread中加入变量 intpri_set;来记录。 (4)改变线程优先级 新增了一个change_priority(structthread*t,intNewPriority); 函数,因为原来的函数thread_set_priority(intNewPriority); 只能改变当前运行的线程的优先级。 改变优先级,如果当前进程是就绪态,那么他在ready_list中,要重新排序,只要从ready_list中删除再插入即可,之前以实现插入排序。 如果当前进程是阻塞态,那么他在block_reason所以记录的链表中,同样 将其删除再插入以排序。 不可能是运行状态,此时运行状态必然是要捐献优先级的进程。 。 (5)恢复线程优先级进,由于线程必然处于运行态,所以只要yield()释放cpu即可,而这在sema_up()函数已经实现。 优先级恢复方法: 当释放一把锁时需要恢复线程优先级。 因为只有占有了锁的线程的优先级才可能因捐献而被改变。 当释放一把锁时,线程只需要查看pri_stack[]这个优先级记录栈的栈顶的这个优先级的改变原因(是一个sema)还在不在本线程的structGetedSemags[]数组中,如果不在就恢复优先级,top--;再查看新的栈顶。 。 如此进行。 原因是可能占有多个锁,释放也不定先释放哪个。 。 实现细节级代码: 其中红色为新增或修改的. thread.h中: #include"synch.h" #defineMAX_SEMA25/*numbersofsemathatathreadcanget*/ #defineMAX_DEEP25/*Maxdeepofnestpriority-donate*/ structGetedSema/*threadgetedsema*/ { structsemaphore*s; intn; }; structPriStore { intpri; structsemaphore*s; }; structthread { /*Ownedbythread.c.*/ tid_ttid;/*Threadidentifier.*/ enumthread_statusstatus;/*Threadstate.*/ charname[16];/*Name(fordebuggingpurposes).*/ uint8_t*stack;/*Savedstackpointer.*/ intpriority;/*Priority.*/ structPriStorepri_stack[MAX_DEEP];/*usedinprioritydonate*/ inttop;/*toppointofpri_stack[]*/ intset_pri;/*whenhavedonatepri,recordsetpri*/ int64_tblock_ticks; structlist_elemallelem;/*Listelementforallthreadslist.*/ structGetedSemags[MAX_SEMA];/*recordthesemaathreadgeted*/ intm_gs;/*Usednumofgs[]*/ structsemaphore*block_reason;/*whyathreadblocked*/ /*Sharedbetweenthread.candsynch.c.*/ structlist_elemelem;/*Listelement.*/ #ifdefUSERPROG /*Ownedbyuserprog/process.c.*/ uint32_t*pagedir;/*Pagedirectory.*/ #endif /*Ownedbythread.c.*/ unsignedmagic;/*Detectsstackoverflow.*/ }; thead.c文件中。 void thread_init(void) { ASSERT(intr_get_level()==INTR_OFF); lock_init(&tid_lock); list_init(&ready_list); list_init(&all_list); /*Setupathreadstructurefortherunningthread.*/ initial_thread=running_thread(); init_thread(initial_thread,"main",PRI_DEFAULT); initial_thread->status=THREAD_RUNNING; initial_thread->tid=allocate_tid(); inti;/*initforgetedsema*/ for(i=0;i { initial_thread->gs[i].n=0; initial_thread->gs[i].s=NULL; } initial_thread->m_gs=0; initial_thread->top=0;/*initforprioriystack*/ initial_thread->block_reason=NULL; initial_thread->set_pri=-1; } voidchange_priority(structthread*t,intnew_priority,structsemaphore*s) { if(new_priority>PRI_MAX||new_priority return; t->pri_stack[t->top].pri=t->priority; t->pri_stack[t->top].s=s; t->top++; ASSERT(t->top<=MAX_DEEP); t->priority=new_priority; if(t->status==THREAD_READY)//&&InList(&ready_list,&t->elem) { list_remove(&t->elem); list_insert_ordered(&ready_list,&t->elem,less_priority,NULL); } elseif(t->status==THREAD_BLOCKED&&NULL! =t->block_reason)//&&InList(&t->block_reason->waiters,&t->elem) { structsemaphore*sema=t->block_reason; list_remove(&t->elem); list_insert_ordered(&sema->waiters,&t->elem,less_priority,NULL); } } synch.c中 void sema_down(structsemaphore*sema) { enumintr_levelold_level; ASSERT(sema! =NULL); ASSERT(! intr_context()); old_level=intr_disable(); while(sema->value==0) { list_insert_ordered(&sema->waiters,&thread_current()->elem,less_priority,NULL); thread_current()->block_reason=sema;//记录线程被阻塞的原因。 thread_block(); } sema->value--; intr_set_level(old_level); } voiddfs_set_priority(structthread*t,void*aux)//递归捐献优先级 { structdfs_aux*da=(structdfs_aux*)aux; inti; for(i=0;i if(t->gs[i].s==da->s) break; if(i { change_priority(t,da->newPriority,da->s); if(t->status==THREAD_BLOCKED&&t->block_reason) { structdfs_auxnewAux; newAux.s=t->block_reason; newAux.newPriority=t->priority; if(t->block_reason! =da->s) thread_foreach(dfs_set_priority,&newAux); } } } void sema_up(structsemaphore*sema) { enumintr_levelold_level; ASSERT(sema! =NULL); structthread*t; old_level=intr_disable(); if(! list_empty(&sema->waiters)) { t=list_entry(list_pop_front(&sema->waiters), structthread,elem); thread_unblock(t); t->block_reason=NULL; } sema->value++; intr_set_level(old_level); thread_yield(); } void lock_acquire(structlock*lock) { ASSERT(lock! =NULL); ASSERT(! intr_context()); ASSERT(! lock_held_by_current_thread(lock)); enumintr_levelold_level; old_level=intr_disable();//becausethread_foreachneeddisableinterupt structsemaphore*sema=&lock->semaphore; if(lock->semaphore.value<=0)//wheherthisthreadwillbeblocked. {//ifyesdfsdonatepriority thread_current()->block_reason=sema; structdfs_auxaux; aux.s=sema; aux.newPriority=thread_current()->priority; thread_foreach(dfs_set_priority,&aux); } else//ifnotegetthelock { structthread*t=thread_current(); inti;//findifthethreadalreadyhavethelock for(i=0;i if(t->gs[i].s==sema) break; if(i t->gs[i].n++; else//ifhavenot { ASSERT(t->m_gs t->m_gs++; t->gs[i].s=sema; t->gs[i].n++; } } sema_down(&lock->semaphore);//发生了两次关闭中断 intr_set_level(old_level); lock->holder=thread_current(); } void lock_release(structlock*lock) { ASSERT(lock! =NULL); ASSERT(lock_held_by_current_thread(lock)); lock->holder=NULL; structsemaphore*sema=&lock->semaphore; structthread*t=thread_current(); t->block_reason=NULL; inti;//realselockshouldcheckifneedrestorepriority for(i=0;i if(t->gs[i].s==sema) break; t->gs[i].n--; if(t->gs[i].n==0) { t->gs[i]=t->gs[t->m_gs-1];//deletethelock t->m_gs--; while(t->top>0)//restorepriority { for(i=0;i if(t->gs[i].s==t->p
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- pintos pro1