zoukankan      html  css  js  c++  java
  • xv6的设计trick(不断更新)

    1、每个进程通过时钟中断出发trap.c中的

    if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER)
    yield();来强制把这个进程置为Runnable状态,yield的实现如下:

    acquire(&ptable.lock); //DOC: yieldlock
    proc->state = RUNNABLE;
    sched();
    release(&ptable.lock);

    在sched中

    swtch(&proc->context, cpu->scheduler); 实现从当前进程的kernel Stack 切换到 CPU中专门负责程序调度的 scheduler Stack,

    (gdb) p /x *cpus[0]->scheduler 
    $7 = {edi = 0x0, esi = 0x80104ea4, ebx = 0x8, ebp = 0x8010c608, 
    eip = 0x80104ab2}

    此时,我们在 sched设置断点

    (gdb)b proc.c:314

    (gdb)s  进入汇编代码

    在swtch的汇编代码中,我们将当前进程的esp所指向的内存地址+8 作为新的上下文的esp,然后保存老寄存值,popl加载新的寄存器的值

    swtch:

       movl %esp, (%eax)

       movl %edx, %esp

    edx 的值就是指向 CPU scheduler的栈底指针的值

    2、磁盘文件块读写

    struct buf* bread(uint dev, uint blockno) {
    struct buf* b;
    b = bget(dev, blockno);
    if (!(b.flags & B_VALID)) {
    iderw(b);
    }
    return b;
    }

    static struct buf* bget(uint dev, uint blockno) {
    struct buf* b;
    acquire(&bcache.lk);
    loop:
    for(b = bcache.head.next; b != &bcache.head; b = b->next) {
    //if the buf is already in the buffer
    if (b->dev == dev && b->blockno == blockno) {
    if (!(b.flags & B_BUSY)) {
    b.flags &= B_BUSY;
    release(&bcache.lk);
    return b;
    }
    sleep(b, &bcache.lk);
    goto loop;
    }
    }
    for (b = bcache.head.prev; b != &bcache.head; b = b->next) {
    if((b.flags & B_BUSY) == 0 && (b.flags & B_DIRTY) == 0) {
    b->dev = dev;
    b->blockno = blockno;
    b->flags = B_BUSY;
    release(&bcache.lk);
    return b;
    }
    }
    panic("there isn't any empty buf");
    }

  • 相关阅读:
    Java 快速入门-06-JDK 目录文件说明
    Java快速入门-05-数组循环条件 实例《延禧攻略》
    腾讯云服务器 选购+远程控制 图文教程
    无法获得锁 /var/lib/dpkg/lock
    Ubuntu 安装 PhpMyAdmin 图文教程
    基于Redis的BloomFilter算法去重
    CAP理论
    Linux常用命令回顾
    基于Solr实现HBase的二级索引
    Solr搜索服务架构图
  • 原文地址:https://www.cnblogs.com/yanchengwang/p/5573857.html
Copyright © 2011-2022 走看看