操作系统课程设计 Pintos 1 ALarm Clock 问题
问题描述:实现linux中的thread.sleep()函数,其功能是让调用他的线程睡眠一段时间(ticks),然后唤醒。pintos 本身的sleep函数void timer_sleep(int 64_t ticks){Int 64_t start = timer_ticks();ASSERT(intr_get_level ==INTR_ON);while(timer_elap...
问题描述:
实现linux中的thread.sleep()函数,其功能是让调用他的线程睡眠一段时间(ticks),然后唤醒。
pintos 本身的sleep函数
void timer_sleep(int 64_t ticks){
Int 64_t start = timer_ticks();
ASSERT(intr_get_level ==INTR_ON);
while(timer_elapsed(start)<ticks)
thread_yield();
}
pintos 本身的sleep函数是忙等待的实现方式,其睡眠应为一种伪睡眠,睡眠的线程不断查询自己的睡眠时间,如果没有到给定的睡眠时长,则将自己放到队列的末端,这一操作持续进行,浪费cpu资源。
改进:我们不让线程去不断查询自己的睡眠时长,而是通过中断机制,在每一次时间终端到来时,判读该线程是否已经休眠够了睡眠时长,若是则唤醒它,否则让他的继续睡眠,在睡眠时间上减一。
为此 我们需要在thread,h的thread结构体中增加block_ticks 这一变量,通过它来初始化睡眠总时长。
同时在thread.c中增加thread_block_ticks_check函数,同时在thread.c的thread_ticks()函数中通过thread_foreach()函数遍历所有线程来唤醒满足唤醒条件的线程。
同时重写 sleep函数 对线程的睡眠时间进行设定,并将该线程阻塞,进入睡眠。
1、添加block_ticks变量
struct thread
{
/* Owned by thread.c. */
tid_t tid; /* Thread identifier. */
enum thread_status status; /* Thread state. */
char name[16]; /* Name (for debugging purposes). */
uint8_t *stack; /* Saved stack pointer. */
int priority; /* Priority. */
long long block_ticks; /*Blocl_ticks */
struct list_elem allelem; /* List element for all threads list. *
/* Shared between thread.c and synch.c. */
struct list_elem elem; /* List element. */
}
2、在thread.c中加入thread_block_ticks_check函数
void thread_block_ticks_check(struct thread *t){
if(t->status ==THREAD_BLOCKED){
if(t->block_ticks ==1){
thread_unblock(t);
}
if(t->block_ticks !=0){
t->block_ticks--;
}
}
}
3、 修改thread.c中的thread_ticks()函数
void
thread_tick (void)
{
struct thread *t = thread_current ();
/* Update statistics. */
if (t == idle_thread)
idle_ticks++;
#ifdef USERPROG
else if (t->pagedir != NULL)
user_ticks++;
#endif
else
kernel_ticks++;
/* Enforce preemption. */
if (++thread_ticks >= TIME_SLICE)
intr_yield_on_return ();
enum intr_level old_level = intr_disable();
thread_foreach(thread_block_ticks_check,NULL);
intr_set_level(old_level);
}
4、重写sleep函数
timer_sleep (int64_t ticks)
{
//int64_t start = timer_ticks ();
//ASSERT (intr_get_level () == INTR_ON);
//while (timer_elapsed (start) < ticks)
//thread_yield ();
if(ticks<=0) return ;
enum intr_level old_level = intr_disable(); //close interupt
thread_current()->block_ticks = ticks;
thread_block();
intr_set_level(old_level);
}
在 /home/xd/os/pintos/src/thread 中
make check
得到结果
更多推荐
所有评论(0)