我是CPU一号车间的阿Q,我又来了!
我们日常的工作就是不断执行代码指令,不过这看似简单的工作背后其实也并不轻松。
咱不能闷着头啥也不管一个劲的只管执行代码,还得和连接在主板上的其他单位打交道。经常保持联系的有键盘、鼠标、磁盘,哦对,还有网卡,这家伙最近把我惹到了,待会再说这事儿。
原以为内存那家伙已经够慢的了,没想到跟上面这几位通个信比他更慢,咱CPU工厂的时间一刻值千金,不能干等着,耽误工夫。后来厂里一合计,想了个叫中断的办法。
在我们车间装了个大灯,这些单位想联系我们办事儿,就先给我们发一个中断信号,大灯就会自动亮起。我们平时工作执行代码指令的时候,每执行一条指令就会瞅一眼看看大灯有没有亮起来。一旦发现灯亮了,就把手头的工作先放一边,去处理一下。
我们记性很差的,等会处理了完了还得回来接着原来的活继续干,为了等会回来还能接的起来,走之前得把当前执行的这个线程的各个寄存器的值,执行到哪里了等等这些信息都保存在这个线程的栈里去。
不过有时候我们在执行非常重要的事情的时候,就不想被他们打断。于是我们又在车间里那个eflags寄存器中设置了一个标记,如果是1我们才允许被打断,如果是0那就算天王老子找我们也不管了。
哦不对,还有一种不可以屏蔽的中断NMI,走得是绿色通道。不过我可不期望有这种事情发生,因为一般都没有好事,不是电源断电就是温度过高,或者总线出了错误等这之类严重的事情。
8259A PIC还有一个问题,找我们办事儿的单位有很多,我们得要区分开来,到底是谁来消息了,而且要是他们一起来找,按什么样优先级顺序处理,也是一件头疼的事情。
为此,厂里单独组建了一个全资的子公司来负责这事儿,他就是可编程中断控制器PIC,外号8259A,其他单位想联系我们都得通过这个PIC,我们只需要和PIC进行对接就可以了。
我们给办事单位都分配了一个编号,叫做中断向量。我们还准备了一个表格叫中断描述符表IDT,表格里记录了很多信息,其中就有处理这个中断号对应的函数地址。我们找PIC拿到编号后就执行处理函数就OK了。
这个表格有点大,足足有256项,咱CPU车间空间有限,放不下,就把它放在内存那家伙那里了,为了能快速找到这个表,专门添置了一个叫idtr的寄存器指向这个表格。
其实除了中断,我们在执行指令的时候如果遇到了异常情况,也会去这个表里执行异常处理函数,最常见的比如遇到了除数是0,内存地址错误等等情况。
这种情况下,我们必须主动放下手里的活,去处理异常,所以我们也说异常是同步的,而中断不知道什么时候发生,所以是异步的。
APIC8259A干的挺不错的,不过后来咱们厂扩大规模,从单核CPU变成了多核,他就有点应付不过来了。
终于有一天,厂里召开会议,把8259A给撤了,成立了一个新的全资子公司叫高级可编程中断控制器APIC,名字就多了个高级两个字,干的活还是一样的。
不过你还别说,这两个字还真不是吹嘘,比8259A不知道高到哪里去了。
这个APIC的新公司一上台,就成立了两个部门,一个叫I/O APIC,负责接待那些要找我们办事儿的单位,一个叫Local APIC,以外包的形式入驻到我CPU的各个车间工作,因为就挨着我们办公,所以取名叫Local。
I/O APIC收到中断信号以后,根据自己的策略就分发到对应的Local APIC,咱们八个车间就可以专心处理了,为我们省了不少事儿。
不仅如此,通过这个外包团队,我们八个车间还能向彼此发起中断请求,我们把这个叫做处理器间中断Inter-Processor Interrupt,简称IPI。
中断亲和性每当网络中有数据包到来,网卡那家伙就发送一个中断消息过来,告诉我们去处理。
不过最近不知道怎么回事,网络数据量激增。咱们厂里明明有8个车间,他非得一个劲的只给我们发消息,搞得我们手头的工作老是被打断,忙得不可开交。
终于,我忍不住了,去找网卡那家伙理论了一番。不过他告诉我,这也不能怪他,分发给谁处理,那是APIC在负责。
想想也是,回头我就去了APIC那里,要求他们分摊一点给别的车间处理。
APIC表示这他们做不了主,得让厂里来决定。
没过几天,厂里开了个会,参会的有各车间代表、APIC负责人,还请了操作系统那边的相关代表过来。
会上,大家为了此事争执不休。
二号车间虎子:“阿Q,谁叫你们一号车间是Bootstrap Processor,你们就多辛苦一点嘛”