code:swap - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Source

  • 负责进程图像在内存和盘交换区之间的传送
  • 传入4个参数:blkno,coreddr,count,rdflg
    • blkno : 磁盘位置起始块号(256字/块)
    • coreddr : 内存起始块号(32字/块)
    • count : 需要传送的内存块数
    • rdflg : 读/写 磁盘 交换区标志,标志常量定义在buf.h
  • 返回值
    • 若错误,则返回B_ERROR
    • 否则,返回0

5192

5193     /*

5194     * swap I/O

5195     */

5196 swap(blkno, coreaddr, count, rdflg)

5197 {

5198     register int *fp;

5199

5200     fp = &swbuf.b_flags;

  • 将swbuf.b_flags的地址赋给fp,使得可以通过fp对swbuf.b_flags进行修改和访问
5201     spl6();
5202     while (*fp&B_BUSY) {

5203          *fp =| B_WANTED;

5204          sleep(fp, PSWP);

5205     }

  • 判断fp是否含B_BUSY
    • 若包含,表明swbuf正在被使用
      • 置B_WANTED标志
      • 以优先级PSWP在fp上睡眠,参看睡眠原因
    • 若不包含,表明swbuf当前空闲,可以使用
5206     *fp = B_BUSY | B_PHYS | rdflg;
  • b_flags置为 B_BUSY(被占用),B_PHPS(传送的是进程图像),rdflg(进行读或写I/O标志)
5207     swbuf.b_dev = swapdev;
  • b_dev置为磁盘盘交换区的设备号
5208     swbuf.b_wcount = - (count<<5); /* 32 w/block */
  • b_wcount存放将要进行传输的字数
    • 传入的参数count为将要进行传输的内存块数,内存每块有32个字,count左移五位(相当于乘以32)可得传输字数
5209     swbuf.b_blkno = blkno;

5210     swbuf.b_addr = coreaddr<<6; /* 64 b/block */

5211     swbuf.b_xmem = (coreaddr>>10) & 077;

  • b_blkno存放磁盘起始块号
  • b_addr 缓存块内存起始地址的低16位(coreaddr为16位(int),左移6位即得低10位,在其拼接6个0 (每块大小为2^6字节))
  • b_xmem 缓存块内存起始地址的高6位(coreaddr为16位(int),右移10位取最后六位,即得高6位,在pdp11/40中只有最后2位有效)
5212     (*bdevsw[swapdev>>8].d_strategy)(&swbuf);
  • 启动磁盘盘交换区设备
  • 将I/O请求块放入该设备I/O请求队列
5213     spl6();
5214     while((*fp&B_DONE)==0)

5215          sleep(fp, PSWP);

5216     if (*fp&B_WANTED)

5217          wakeup(fp);

  • 判断本次I/O是否结束
    • 若没有结束则在fp上以优先级PSWP睡眠
    • 若已经结束,再判断是否含B_WANTED
      • 若有B_WANTED则唤醒所有等待使用该swbuf的进程
5218     spl0();
5219     *fp =& ~(B_BUSY|B_WANTED);
  • 在本次I/O完毕后去掉B_BUSY,B_WANTED标志,以供其他进程使用
5220     return(*fp&B_ERROR);
  • 如果 I/O 出错,则返回B_ERROR
  • 否则,返回0
5221 }

5222     /* -------------------------*/

Ref

Caller

⚠️ **GitHub.com Fallback** ⚠️