设计了一个ring buffer,一个中断进程负责往里面写入数据,一个后台进程负责读取数据。
数据每次写入就对cnt++,每次读取就cnt--,运行一段时间之后,发现写指针和读指针对不上了,中间隔开了一段距离。
查了很久,发现很有可能是这个cnt++出了问题,因为++操作不是原子操作,需要先mov出来,++,然后写回,这样的话有可能在中断里++之后又被原先被中断的--操作覆盖。
详细的过程分析:
1. CPU执行到cnt--,
2. cnt的值(架设==5)被mov到寄存器进行--操作
3. 寄存器完成操作得到结果4
4. 把寄存器的结果写回变量的内存地址,最终得到4.
假如在第2步之后发生了中断,那么情况是:
1. CPU执行到cnt--,
2. cnt的值(架设==5)被mov到寄存器进行--操作
3. 发生中断,中断程序把临时变量入栈,保护现场,也就是把寄存器里cnt=5保存起来
4. 中断里面获取cnt的值,也是5,放入寄存器进行++运算
5. 把运算结果6写回变量的内存地址,此时内存里的值为6
6. 中断程序退出之前恢复现场,把之前的变量出栈,寄存器恢复为5并进行--运算
7. 寄存器完成操作得到结果4
8. 把寄存器的结果写回变量的内存地址,最终得到4.
这样,最终的结果就好比根本没用执行cnt++,实际上只执行了cnt--。
解决的办法:
暂时我想到的是,在需要做cnt--之前先关闭中断,等完成后重新打开中断。