Linux 0.12中bread函数步骤
发布时间:2021-12-22 12:53:15 所属栏目:PHP教程 来源:互联网
导读:总结了Linux0.12中的bread函数大致流程,还有些细节,待以后解决 假设有四个任务,任务A,任务B,任务C,任务D(不包括任务0),任务A,B,C,D都将在内核态执行bread函数,但是任务A最先执行,任务B其次,接着任务C,而任务D是在任务A执行完bread后才执行bre
总结了Linux0.12中的bread函数大致流程,还有些细节,待以后解决 假设有四个任务,任务A,任务B,任务C,任务D(不包括任务0),任务A,B,C,D都将在内核态执行bread函数,但是任务A最先执行,任务B其次,接着任务C,而任务D是在任务A执行完bread后才执行bread,并且,任务A和D的dev和block相同,和其余两个任务的block都不相同。 任务A:dev=3,block=7 任务B:dev=3,block=6 任务C:dev=3,block=18 任务D:dev=3,block=7 并且,A任务是第一个插入请求队列的请求 好,现在开始分析。 首先,任务A通过getblk()得到了一个未上锁(如果是get_hash_table直接得到,可能uptodate=1或dirt=1,可以看我上一篇画的getblk流程图) 的缓冲头bh,我们假设,任务A是从free_list中得到的bh,因此,lock和uptodate都为0,接着,任务A进入ll_rw_block(READ,bh)函数,经历make_request(major,READ,bh),在make_request()后,创建了一个request结构: PS:在make_request()中对bh上了锁,表明要对缓冲块进行操作 lock_buffer(bh); 然后该req通过add_request(major+blk_dev,req)插入到请求表中,对应blk_dev[3], : 由于任务A是第一个请求,因此,在插入队列后,直接执行(dev->current_request_fn)(),也就是do_hd_request()。 注意,由于假设除ABCD外没有其他任务操作缓冲块,因此,除了时钟中断外没有设备驱动中断! do_hd_request()会先计算出要从硬盘中读取的位置,磁头号、柱面号和扇区号,然后调用hd_out(...,WIN_READ,&read_init) 在hd_out()中,会向硬盘发送指令,...,outb(cmd,++port);发送完后,一直return(后面的操作交给磁盘驱动器,程序不管了),return到ll_rw_block()下面一句wait_on_buffer(bh)。 static inline void wait_on_buffer(struct buffer_head * bh) { cli(); while (bh->b_lock) sleep_on(&bh->b_wait); sti(); } 之后任务A会在bh->b_wait队列上睡眠,主动调度到其他任务,直到被唤醒,并且b_lock=0(等待硬盘中断)! 好,下面该任务B出场了,假设此时任务A等待的硬盘中断还没有来,任务B也在经历任务A之前经历的事情,lock_buffer(bh)...当执行到add_request()时,发现,请求队列中已经有了一个请求(任务A的),于是执行Plan B,将自己的请求插入请求列表后return(这个请求会在任务A的中断程序中实现) ![]() (编辑:云计算网_泰州站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |