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");
    }

  • 相关阅读:
    vim 编辑器使用
    PHP高并发高负载系统架构(转载)
    类的使用
    linux下EC20 4G模块驱动移植
    linux 4G模块拨号脚本
    linux4.1.4上移植ME909s-821,MU609 4G模块驱动
    shell脚本语之运算符
    vim的列编辑操作
    linux下普通用户添加 sudo 免密码
    4G模块在AM335x上的移植
  • 原文地址:https://www.cnblogs.com/yanchengwang/p/5573857.html
Copyright © 2011-2022 走看看