Loading

6.S081 lab7 Multithreading

# Uthread: switching between threads

  • 为每个线程添加一个context结构以用于保存/还原寄存器,这部分可以直接把xv6context搬过来

    image.png

image.png

  • thread_yield类似于xv6中的yield,它的作用是把当前的进程设置为RUNNABLE,并调用thread_schedule切换至下一个可执行的线程。main函数对a,b,c三个线程都调用了thread_create,该函数应设置线程的ra(返回地址)和sp(栈顶指针),再调用thread_yield切换线程。由于thread_create函数只在创建线程时调用,故ra应该设置为线程的开始位置,也就是funcsp设置为线程的栈顶t->stack+STACK_SIZE(这里特别注意栈顶不是t->stack!)

    image.png

  • 在thread_scheduler中加入thread_switch,并且补充thread_switch

    image.png

    切换线程时,要保存和恢复寄存器。thread_switch函数可以直接把xv6swtch搬过来

    	.text
    	/*
             * save the old thread's registers,
             * restore the new thread's registers.
             */
    	.globl thread_switch
    thread_switch:
            sd ra, 0(a0)
            sd sp, 8(a0)
            sd s0, 16(a0)
            sd s1, 24(a0)
            sd s2, 32(a0)
            sd s3, 40(a0)
            sd s4, 48(a0)
            sd s5, 56(a0)
            sd s6, 64(a0)
            sd s7, 72(a0)
            sd s8, 80(a0)
            sd s9, 88(a0)
            sd s10, 96(a0)
            sd s11, 104(a0)
    
            ld ra, 0(a1)
            ld sp, 8(a1)
            ld s0, 16(a1)
            ld s1, 24(a1)
            ld s2, 32(a1)
            ld s3, 40(a1)
            ld s4, 48(a1)
            ld s5, 56(a1)
            ld s6, 64(a1)
            ld s7, 72(a1)
            ld s8, 80(a1)
            ld s9, 88(a1)
            ld s10, 96(a1)
            ld s11, 104(a1)
            ret
    

#Using threads

  • put操作中,用insert添加键时,采用的是头插法。若不使用锁,当多个线程同时对某个哈希桶进行insert时候,会导致一个键被覆盖。

  • 为所有哈希桶添加锁

    image.png

    main函数中初始化所有锁

    image.png

    putget中加入获取锁和释放锁的操作

    image.png

    image.png

#Barrier

  • 每次进入barrier时,线程首先获取锁,对nthread+1,也就是已到达屏障的线程数增加了一个。如果已到达屏障的线程数与总线程数相等,说明所有线程都到达了,对轮数round+1,并且唤醒所有休眠线程,若不相等, 则调用wait让线程释放锁并且休眠。

    static void 
    barrier()
    {
      pthread_mutex_lock(&bstate.barrier_mutex);
      bstate.nthread++;
      if (bstate.nthread == nthread){
        bstate.round++;
        bstate.nthread = 0;
        pthread_cond_broadcast(&bstate.barrier_cond);
      }
      else{
        pthread_cond_wait(&bstate.barrier_cond, &bstate.barrier_mutex);
      }
        pthread_mutex_unlock(&bstate.barrier_mutex);
    }
    
posted @ 2022-01-18 11:06  Kyoz1  阅读(49)  评论(0)    收藏  举报
7