code:swap - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki
- 负责进程图像在内存和盘交换区之间的传送
- 传入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;
5201 spl6();
- 将swbuf.b_flags的地址赋给fp,使得可以通过fp对swbuf.b_flags进行修改和访问
5202 while (*fp&B_BUSY) {
5203 *fp =| B_WANTED;
5204 sleep(fp, PSWP);
5205 }
5206 *fp = B_BUSY | B_PHYS | rdflg;
- 判断fp是否含B_BUSY
- 若包含,表明swbuf正在被使用
- 置B_WANTED标志
- 以优先级PSWP在fp上睡眠,参看睡眠原因
- 若不包含,表明swbuf当前空闲,可以使用
5207 swbuf.b_dev = swapdev;
- b_flags置为 B_BUSY(被占用),B_PHPS(传送的是进程图像),rdflg(进行读或写I/O标志)
5208 swbuf.b_wcount = - (count<<5); /* 32 w/block */
- b_dev置为磁盘盘交换区的设备号
5209 swbuf.b_blkno = blkno;
- b_wcount存放将要进行传输的字数
- 传入的参数count为将要进行传输的内存块数,内存每块有32个字,count左移五位(相当于乘以32)可得传输字数
5210 swbuf.b_addr = coreaddr<<6; /* 64 b/block */
5211 swbuf.b_xmem = (coreaddr>>10) & 077;
5212 (*bdevsw[swapdev>>8].d_strategy)(&swbuf);
- 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位有效)
5213 spl6();
- 启动磁盘盘交换区设备
- 将I/O请求块放入该设备I/O请求队列
5214 while((*fp&B_DONE)==0)
5215 sleep(fp, PSWP);
5216 if (*fp&B_WANTED)
5217 wakeup(fp);
5218 spl0();
- 判断本次I/O是否结束
- 若没有结束则在fp上以优先级PSWP睡眠
- 若已经结束,再判断是否含B_WANTED
- 若有B_WANTED则唤醒所有等待使用该swbuf的进程
5219 *fp =& ~(B_BUSY|B_WANTED);
5220 return(*fp&B_ERROR);
- 在本次I/O完毕后去掉B_BUSY,B_WANTED标志,以供其他进程使用
5221 }
- 如果 I/O 出错,则返回B_ERROR
- 否则,返回0
5222 /* -------------------------*/