问题描述
根据“Barrier Litmus Tests and Cookbook”文档,我用 C 编写了一个 claim_lock 函数。我检查了生成的代码,看起来不错,但没有用。
import os
from PyQt5.QtWidgets import QCheckBox,QLineEdit,QWidget,QApplication,QVBoxLayout
from PyQt5.QtCore import QEvent,Qt
class CtrlaDel(QWidget):
def __init__(self):
super().__init__()
self.setwindowTitle("Key Press Event")
self.le = QLineEdit()
self.cb = QCheckBox()
self.cb.setChecked(True)
self.vBox = QVBoxLayout(self)
self.vBox.addWidget(self.le)
self.vBox.addWidget(self.cb)
self.le.installEventFilter(self)
def eventFilter(self,source,event):
if event.type() == QEvent.KeyPress and source is self.le:
print("ddddsdsdsdsdsdsds")
if event.key() == Qt.Key_Backspace or event.key() == Qt.Key_Delete and source is self.le:
print("ddd")
if len(self.le.text()) <= 1:
self.cb.setChecked(False)
if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_A:
print("I am inside of Ctrl+A")
if event.key() == Qt.Key_Delete:
print("I am Inside of Delete")
self.cb.setChecked(False)
self.checkstatus = 0
return True
return super(CtrlaDel,self).eventFilter(source,event)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
mainwindow = CtrlaDel()
mainwindow.show()
sys.exit(app.exec_())
// This code conforms to the section 7.2 of PRD03-GENC-007826:
// "Acquiring and Releasing a Lock"
static inline void claim_lock( uint32_t volatile *lock )
{
uint32_t Failed = 1;
uint32_t value;
while (Failed) {
asm volatile ( "ldrex %[value],[%[lock]]"
: [value] "=&r" (value)
: [lock] "r" (lock) );
if (value == 0) {
// The Failed and lock registers are not allowed to be the same,so
// pretend to gcc that the lock pointer may be written as well as read.
asm volatile ( "strex %[Failed],%[value],[%[lock]]"
: [Failed] "=&r" (Failed),[lock] "+r" (lock)
: [value] "r" (1) );
}
else {
asm ( "clrex" );
}
}
asm ( "dmb sy" );
}
对应的发布函数:
1000: e3a03001 mov r3,#1
1004: e1902f9f ldrex r2,[r0]
1008: e3520000 cmp r2,#0
100c: 1a000004 bne 1024 <claim_lock+0x24>
1010: e1802f93 strex r2,r3,[r0]
1014: e3520000 cmp r2,#0
1018: 1afffff9 bne 1004 <claim_lock+0x4>
101c: f57ff05f dmb sy
1020: e12fff1e bx lr
1024: f57ff01f clrex
1028: eafffff5 b 1004 <claim_lock+0x4>
它在 QEMU 中工作,但要么挂起,要么允许所有内核在真实硬件(RaspBerry Pi 3 Cortex-A53)上“声明”所谓的“锁定”。
解决方法
如果出现以下情况,LDREX 指令将挂起内核(除非我的测试未报告异常):
- 未启用 MMU
- 没有缓存包含锁的虚拟内存区域
如果出现以下情况,核心似乎会忽略彼此的声明:
- 尚未启用对称多处理
SMP 启用机制似乎因设备而异;检查特定内核的 TRM,它超出了 ARM ARM 的范围。
对于 Cortex-A53,要设置的位是 SMPEN,即 CPU 扩展控制寄存器 CPUECTLR 的第 6 位。
较早的设备具有辅助控制寄存器的第 5 位,例如 (ARM11 MPcore),其中还需要考虑 SCU。我没有这样的设备,但正是在该文档中我第一次注意到 SMP/nAMP 位。